diff --git a/api/current.xml b/api/current.xml
index 1ab1f5e..c2e84be 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -28137,6 +28137,19 @@
 <parameter name="syncResult" type="android.content.SyncResult">
 </parameter>
 </method>
+<method name="onSyncCanceled"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="thread" type="java.lang.Thread">
+</parameter>
+</method>
 <field name="LOG_SYNC_DETAILS"
  type="int"
  transient="false"
diff --git a/core/java/android/content/AbstractSyncableContentProvider.java b/core/java/android/content/AbstractSyncableContentProvider.java
deleted file mode 100644
index 5903c83..0000000
--- a/core/java/android/content/AbstractSyncableContentProvider.java
+++ /dev/null
@@ -1,758 +0,0 @@
-package android.content;
-
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.Cursor;
-import android.net.Uri;
-import android.accounts.OnAccountsUpdateListener;
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.provider.SyncConstValue;
-import android.util.Config;
-import android.util.Log;
-import android.os.Bundle;
-import android.text.TextUtils;
-
-import java.util.Collections;
-import java.util.Map;
-import java.util.Vector;
-import java.util.ArrayList;
-import java.util.Set;
-import java.util.HashSet;
-
-import com.google.android.collect.Maps;
-
-/**
- * A specialization of the ContentProvider that centralizes functionality
- * used by ContentProviders that are syncable. It also wraps calls to the ContentProvider
- * inside of database transactions.
- *
- * @hide
- */
-public abstract class AbstractSyncableContentProvider extends SyncableContentProvider {
-    private static final String TAG = "SyncableContentProvider";
-    protected SQLiteOpenHelper mOpenHelper;
-    protected SQLiteDatabase mDb;
-    private final String mDatabaseName;
-    private final int mDatabaseVersion;
-    private final Uri mContentUri;
-
-    /** the account set in the last call to onSyncStart() */
-    private Account mSyncingAccount;
-
-    private SyncStateContentProviderHelper mSyncState = null;
-
-    private static final String[] sAccountProjection =
-            new String[] {SyncConstValue._SYNC_ACCOUNT, SyncConstValue._SYNC_ACCOUNT_TYPE};
-
-    private boolean mIsTemporary;
-
-    private AbstractTableMerger mCurrentMerger = null;
-    private boolean mIsMergeCancelled = false;
-
-    private static final String SYNC_ACCOUNT_WHERE_CLAUSE =
-            SyncConstValue._SYNC_ACCOUNT + "=? AND " + SyncConstValue._SYNC_ACCOUNT_TYPE + "=?";
-
-    protected boolean isTemporary() {
-        return mIsTemporary;
-    }
-
-    private final ThreadLocal<Boolean> mApplyingBatch = new ThreadLocal<Boolean>();
-    private final ThreadLocal<Set<Uri>> mPendingBatchNotifications = new ThreadLocal<Set<Uri>>();
-
-    /**
-     * Indicates whether or not this ContentProvider contains a full
-     * set of data or just diffs. This knowledge comes in handy when
-     * determining how to incorporate the contents of a temporary
-     * provider into a real provider.
-     */
-    private boolean mContainsDiffs;
-
-    /**
-     * Initializes the AbstractSyncableContentProvider
-     * @param dbName the filename of the database
-     * @param dbVersion the current version of the database schema
-     * @param contentUri The base Uri of the syncable content in this provider
-     */
-    public AbstractSyncableContentProvider(String dbName, int dbVersion, Uri contentUri) {
-        super();
-
-        mDatabaseName = dbName;
-        mDatabaseVersion = dbVersion;
-        mContentUri = contentUri;
-        mIsTemporary = false;
-        setContainsDiffs(false);
-        if (Config.LOGV) {
-            Log.v(TAG, "created SyncableContentProvider " + this);
-        }
-    }
-
-    /**
-     * Close resources that must be closed. You must call this to properly release
-     * the resources used by the AbstractSyncableContentProvider.
-     */
-    public void close() {
-        if (mOpenHelper != null) {
-            mOpenHelper.close();  // OK to call .close() repeatedly.
-        }
-    }
-
-    /**
-     * Override to create your schema and do anything else you need to do with a new database.
-     * This is run inside a transaction (so you don't need to use one).
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     */
-    protected void bootstrapDatabase(SQLiteDatabase db) {}
-
-    /**
-     * Override to upgrade your database from an old version to the version you specified.
-     * Don't set the DB version; this will automatically be done after the method returns.
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     *
-     * @param oldVersion version of the existing database
-     * @param newVersion current version to upgrade to
-     * @return true if the upgrade was lossless, false if it was lossy
-     */
-    protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
-    /**
-     * Override to do anything (like cleanups or checks) you need to do after opening a database.
-     * Does nothing by default.  This is run inside a transaction (so you don't need to use one).
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     */
-    protected void onDatabaseOpened(SQLiteDatabase db) {}
-
-    private class DatabaseHelper extends SQLiteOpenHelper {
-        DatabaseHelper(Context context, String name) {
-            // Note: context and name may be null for temp providers
-            super(context, name, null, mDatabaseVersion);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            bootstrapDatabase(db);
-            mSyncState.createDatabase(db);
-            if (!isTemporary()) {
-		ContentResolver.requestSync(null /* all accounts */,
-                    mContentUri.getAuthority(), new Bundle());
-	    }
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            if (!upgradeDatabase(db, oldVersion, newVersion)) {
-                mSyncState.discardSyncData(db, null /* all accounts */);
-                ContentResolver.requestSync(null /* all accounts */,
-                        mContentUri.getAuthority(), new Bundle());
-            }
-        }
-
-        @Override
-        public void onOpen(SQLiteDatabase db) {
-            onDatabaseOpened(db);
-            mSyncState.onDatabaseOpened(db);
-        }
-    }
-
-    @Override
-    public boolean onCreate() {
-        if (isTemporary()) throw new IllegalStateException("onCreate() called for temp provider");
-        mOpenHelper = new AbstractSyncableContentProvider.DatabaseHelper(getContext(),
-                mDatabaseName);
-        mSyncState = new SyncStateContentProviderHelper(mOpenHelper);
-        AccountManager.get(getContext()).addOnAccountsUpdatedListener(
-                new OnAccountsUpdateListener() {
-                    public void onAccountsUpdated(Account[] accounts) {
-                        // Some providers override onAccountsChanged(); give them a database to
-                        // work with.
-                        mDb = mOpenHelper.getWritableDatabase();
-                        // Only call onAccountsChanged on GAIA accounts; otherwise, the contacts and
-                        // calendar providers will choke as they try to sync unknown accounts with
-                        // AbstractGDataSyncAdapter, which will put acore into a crash loop
-                        ArrayList<Account> gaiaAccounts = new ArrayList<Account>();
-                        for (Account acct: accounts) {
-                            if (acct.type.equals("com.google")) {
-                                gaiaAccounts.add(acct);
-                            }
-                        }
-                        accounts = new Account[gaiaAccounts.size()];
-                        int i = 0;
-                        for (Account acct: gaiaAccounts) {
-                            accounts[i++] = acct;
-                        }
-                        onAccountsChanged(accounts);
-                        TempProviderSyncAdapter syncAdapter = getTempProviderSyncAdapter();
-                        if (syncAdapter != null) {
-                            syncAdapter.onAccountsChanged(accounts);
-                        }
-                    }
-                }, null /* handler */, true /* updateImmediately */);
-
-        return true;
-    }
-    /**
-     * Get a non-persistent instance of this content provider.
-     * You must call {@link #close} on the returned
-     * SyncableContentProvider when you are done with it.
-     *
-     * @return a non-persistent content provider with the same layout as this
-     * provider.
-     */
-    public AbstractSyncableContentProvider getTemporaryInstance() {
-        AbstractSyncableContentProvider temp;
-        try {
-            temp = getClass().newInstance();
-        } catch (InstantiationException e) {
-            throw new RuntimeException("unable to instantiate class, "
-                    + "this should never happen", e);
-        } catch (IllegalAccessException e) {
-            throw new RuntimeException(
-                    "IllegalAccess while instantiating class, "
-                            + "this should never happen", e);
-        }
-
-        // Note: onCreate() isn't run for the temp provider, and it has no Context.
-        temp.mIsTemporary = true;
-        temp.setContainsDiffs(true);
-        temp.mOpenHelper = temp.new DatabaseHelper(null, null);
-        temp.mSyncState = new SyncStateContentProviderHelper(temp.mOpenHelper);
-        if (!isTemporary()) {
-            mSyncState.copySyncState(
-                    mOpenHelper.getReadableDatabase(),
-                    temp.mOpenHelper.getWritableDatabase(),
-                    getSyncingAccount());
-        }
-        return temp;
-    }
-
-    public SQLiteDatabase getDatabase() {
-       if (mDb == null) mDb = mOpenHelper.getWritableDatabase();
-       return mDb;
-    }
-
-    public boolean getContainsDiffs() {
-        return mContainsDiffs;
-    }
-
-    public void setContainsDiffs(boolean containsDiffs) {
-        if (containsDiffs && !isTemporary()) {
-            throw new IllegalStateException(
-                    "only a temporary provider can contain diffs");
-        }
-        mContainsDiffs = containsDiffs;
-    }
-
-    /**
-     * Each subclass of this class should define a subclass of {@link
-     * android.content.AbstractTableMerger} for each table they wish to merge.  It
-     * should then override this method and return one instance of
-     * each merger, in sequence.  Their {@link
-     * android.content.AbstractTableMerger#merge merge} methods will be called, one at a
-     * time, in the order supplied.
-     *
-     * <p>The default implementation returns an empty list, so that no
-     * merging will occur.
-     * @return A sequence of subclasses of {@link
-     * android.content.AbstractTableMerger}, one for each table that should be merged.
-     */
-    protected Iterable<? extends AbstractTableMerger> getMergers() {
-        return Collections.emptyList();
-    }
-
-    @Override
-    public final int update(final Uri url, final ContentValues values,
-            final String selection, final String[] selectionArgs) {
-        mDb = mOpenHelper.getWritableDatabase();
-        final boolean notApplyingBatch = !applyingBatch();
-        if (notApplyingBatch) {
-            mDb.beginTransaction();
-        }
-        try {
-            if (isTemporary() && mSyncState.matches(url)) {
-                int numRows = mSyncState.asContentProvider().update(
-                        url, values, selection, selectionArgs);
-                if (notApplyingBatch) {
-                    mDb.setTransactionSuccessful();
-                }
-                return numRows;
-            }
-
-            int result = updateInternal(url, values, selection, selectionArgs);
-            if (notApplyingBatch) {
-                mDb.setTransactionSuccessful();
-            }
-            if (!isTemporary() && result > 0) {
-                if (notApplyingBatch) {
-                    getContext().getContentResolver().notifyChange(url, null /* observer */,
-                            changeRequiresLocalSync(url));
-                } else {
-                    mPendingBatchNotifications.get().add(url);
-                }
-            }
-            return result;
-        } finally {
-            if (notApplyingBatch) {
-                mDb.endTransaction();
-            }
-        }
-    }
-
-    @Override
-    public final int delete(final Uri url, final String selection,
-            final String[] selectionArgs) {
-        mDb = mOpenHelper.getWritableDatabase();
-        final boolean notApplyingBatch = !applyingBatch();
-        if (notApplyingBatch) {
-            mDb.beginTransaction();
-        }
-        try {
-            if (isTemporary() && mSyncState.matches(url)) {
-                int numRows = mSyncState.asContentProvider().delete(url, selection, selectionArgs);
-                if (notApplyingBatch) {
-                    mDb.setTransactionSuccessful();
-                }
-                return numRows;
-            }
-            int result = deleteInternal(url, selection, selectionArgs);
-            if (notApplyingBatch) {
-                mDb.setTransactionSuccessful();
-            }
-            if (!isTemporary() && result > 0) {
-                if (notApplyingBatch) {
-                    getContext().getContentResolver().notifyChange(url, null /* observer */,
-                            changeRequiresLocalSync(url));
-                } else {
-                    mPendingBatchNotifications.get().add(url);
-                }
-            }
-            return result;
-        } finally {
-            if (notApplyingBatch) {
-                mDb.endTransaction();
-            }
-        }
-    }
-
-    private boolean applyingBatch() {
-        return mApplyingBatch.get() != null && mApplyingBatch.get();
-    }
-
-    @Override
-    public final Uri insert(final Uri url, final ContentValues values) {
-        mDb = mOpenHelper.getWritableDatabase();
-        final boolean notApplyingBatch = !applyingBatch();
-        if (notApplyingBatch) {
-            mDb.beginTransaction();
-        }
-        try {
-            if (isTemporary() && mSyncState.matches(url)) {
-                Uri result = mSyncState.asContentProvider().insert(url, values);
-                if (notApplyingBatch) {
-                    mDb.setTransactionSuccessful();
-                }
-                return result;
-            }
-            Uri result = insertInternal(url, values);
-            if (notApplyingBatch) {
-                mDb.setTransactionSuccessful();
-            }
-            if (!isTemporary() && result != null) {
-                if (notApplyingBatch) {
-                    getContext().getContentResolver().notifyChange(url, null /* observer */,
-                            changeRequiresLocalSync(url));
-                } else {
-                    mPendingBatchNotifications.get().add(url);
-                }
-            }
-            return result;
-        } finally {
-            if (notApplyingBatch) {
-                mDb.endTransaction();
-            }
-        }
-    }
-
-    @Override
-    public final int bulkInsert(final Uri uri, final ContentValues[] values) {
-        int size = values.length;
-        int completed = 0;
-        final boolean isSyncStateUri = mSyncState.matches(uri);
-        mDb = mOpenHelper.getWritableDatabase();
-        mDb.beginTransaction();
-        try {
-            for (int i = 0; i < size; i++) {
-                Uri result;
-                if (isTemporary() && isSyncStateUri) {
-                    result = mSyncState.asContentProvider().insert(uri, values[i]);
-                } else {
-                    result = insertInternal(uri, values[i]);
-                    mDb.yieldIfContended();
-                }
-                if (result != null) {
-                    completed++;
-                }
-            }
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-        if (!isTemporary() && completed == size) {
-            getContext().getContentResolver().notifyChange(uri, null /* observer */,
-                    changeRequiresLocalSync(uri));
-        }
-        return completed;
-    }
-
-    /**
-     * <p>
-     * Start batch transaction. {@link #endTransaction} MUST be called after 
-     * calling this method. Those methods should be used like this:
-     * </p>
-     *
-     * <pre class="prettyprint">
-     * boolean successful = false;
-     * beginBatch()
-     * try {
-     *     // Do something related to mDb
-     *     successful = true;
-     *     return ret;
-     * } finally {
-     *     endBatch(successful);
-     * }
-     * </pre>
-     *
-     * @hide This method should be used only when {@link ContentProvider#applyBatch} is not enough and must be
-     * used with {@link #endBatch}.
-     * e.g. If returned value has to be used during one transaction, this method might be useful.
-     */
-    public final void beginBatch() {
-        // initialize if this is the first time this thread has applied a batch
-        if (mApplyingBatch.get() == null) {
-            mApplyingBatch.set(false);
-            mPendingBatchNotifications.set(new HashSet<Uri>());
-        }
-
-        if (applyingBatch()) {
-            throw new IllegalStateException(
-                    "applyBatch is not reentrant but mApplyingBatch is already set");
-        }
-        SQLiteDatabase db = getDatabase();
-        db.beginTransaction();
-        boolean successful = false;
-        try {
-            mApplyingBatch.set(true);
-            successful = true;
-        } finally {
-            if (!successful) {
-                // Something unexpected happened. We must call endTransaction() at least.
-                db.endTransaction();
-            }
-        }
-    }
-
-    /**
-     * <p>
-     * Finish batch transaction. If "successful" is true, try to call
-     * mDb.setTransactionSuccessful() before calling mDb.endTransaction().
-     * This method MUST be used with {@link #beginBatch()}.
-     * </p>
-     *
-     * @hide This method must be used with {@link #beginTransaction}
-     */
-    public final void endBatch(boolean successful) {
-        try {
-            if (successful) {
-                // setTransactionSuccessful() must be called just once during opening the
-                // transaction.
-                mDb.setTransactionSuccessful();
-            }
-        } finally {
-            mApplyingBatch.set(false);
-            getDatabase().endTransaction();
-            for (Uri url : mPendingBatchNotifications.get()) {
-                getContext().getContentResolver().notifyChange(url, null /* observer */,
-                        changeRequiresLocalSync(url));
-            }
-        }
-    }
-
-    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
-            throws OperationApplicationException {
-        boolean successful = false;
-        beginBatch();
-        try {
-            ContentProviderResult[] results = super.applyBatch(operations);
-            successful = true;
-            return results;
-        } finally {
-            endBatch(successful);
-        }
-    }
-
-    /**
-     * Check if changes to this URI can be syncable changes.
-     * @param uri the URI of the resource that was changed
-     * @return true if changes to this URI can be syncable changes, false otherwise
-     */
-    public boolean changeRequiresLocalSync(Uri uri) {
-        return true;
-    }
-
-    @Override
-    public final Cursor query(final Uri url, final String[] projection,
-            final String selection, final String[] selectionArgs,
-            final String sortOrder) {
-        mDb = mOpenHelper.getReadableDatabase();
-        if (isTemporary() && mSyncState.matches(url)) {
-            return mSyncState.asContentProvider().query(
-                    url, projection, selection,  selectionArgs, sortOrder);
-        }
-        return queryInternal(url, projection, selection, selectionArgs, sortOrder);
-    }
-
-    /**
-     * Called right before a sync is started.
-     *
-     * @param context the sync context for the operation
-     * @param account
-     */
-    public void onSyncStart(SyncContext context, Account account) {
-        if (account == null) {
-            throw new IllegalArgumentException("you passed in an empty account");
-        }
-        mSyncingAccount = account;
-    }
-
-    /**
-     * Called right after a sync is completed
-     *
-     * @param context the sync context for the operation
-     * @param success true if the sync succeeded, false if an error occurred
-     */
-    public void onSyncStop(SyncContext context, boolean success) {
-    }
-
-    /**
-     * The account of the most recent call to onSyncStart()
-     * @return the account
-     */
-    public Account getSyncingAccount() {
-        return mSyncingAccount;
-    }
-
-    /**
-     * Merge diffs from a sync source with this content provider.
-     *
-     * @param context the SyncContext within which this merge is taking place
-     * @param diffs A temporary content provider containing diffs from a sync
-     *   source.
-     * @param result a MergeResult that contains information about the merge, including
-     *   a temporary content provider with the same layout as this provider containing
-     * @param syncResult
-     */
-    public void merge(SyncContext context, SyncableContentProvider diffs,
-            TempProviderSyncResult result, SyncResult syncResult) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
-            synchronized(this) {
-                mIsMergeCancelled = false;
-            }
-            Iterable<? extends AbstractTableMerger> mergers = getMergers();
-            try {
-                for (AbstractTableMerger merger : mergers) {
-                    synchronized(this) {
-                        if (mIsMergeCancelled) break;
-                        mCurrentMerger = merger;
-                    }
-                    merger.merge(context, getSyncingAccount(), diffs, result, syncResult, this);
-                }
-                if (mIsMergeCancelled) return;
-                if (diffs != null) {
-                    mSyncState.copySyncState(
-                        ((AbstractSyncableContentProvider)diffs).mOpenHelper.getReadableDatabase(),
-                        mOpenHelper.getWritableDatabase(),
-                        getSyncingAccount());
-                }
-            } finally {
-                synchronized (this) {
-                    mCurrentMerger = null;
-                }
-            }
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-
-    /**
-     * Invoked when the active sync has been canceled. Sets the sync state of this provider and
-     * its merger to canceled.
-     */
-    public void onSyncCanceled() {
-        synchronized (this) {
-            mIsMergeCancelled = true;
-            if (mCurrentMerger != null) {
-                mCurrentMerger.onMergeCancelled();
-            }
-        }
-    }
-
-
-    public boolean isMergeCancelled() {
-        return mIsMergeCancelled;
-    }
-
-    /**
-     * Subclasses should override this instead of update(). See update()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract int updateInternal(Uri url, ContentValues values,
-            String selection, String[] selectionArgs);
-
-    /**
-     * Subclasses should override this instead of delete(). See delete()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
-
-    /**
-     * Subclasses should override this instead of insert(). See insert()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract Uri insertInternal(Uri url, ContentValues values);
-
-    /**
-     * Subclasses should override this instead of query(). See query()
-     * for details.
-     *
-     * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
-     * block for performance reasons. If an implementation needs atomic access
-     * to the database the lock can be acquired then.
-     */
-    protected abstract Cursor queryInternal(Uri url, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder);
-
-    /**
-     * Make sure that there are no entries for accounts that no longer exist
-     * @param accountsArray the array of currently-existing accounts
-     */
-    protected void onAccountsChanged(Account[] accountsArray) {
-        Map<Account, Boolean> accounts = Maps.newHashMap();
-        for (Account account : accountsArray) {
-            accounts.put(account, false);
-        }
-
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        Map<String, String> tableMap = db.getSyncedTables();
-        Vector<String> tables = new Vector<String>();
-        tables.addAll(tableMap.keySet());
-        tables.addAll(tableMap.values());
-
-        db.beginTransaction();
-        try {
-            mSyncState.onAccountsChanged(accountsArray);
-            for (String table : tables) {
-                deleteRowsForRemovedAccounts(accounts, table);
-            }
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    /**
-     * A helper method to delete all rows whose account is not in the accounts
-     * map. The accountColumnName is the name of the column that is expected
-     * to hold the account. If a row has an empty account it is never deleted.
-     *
-     * @param accounts a map of existing accounts
-     * @param table the table to delete from
-     */
-    protected void deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts, String table) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        Cursor c = db.query(table, sAccountProjection, null, null,
-                "_sync_account, _sync_account_type", null, null);
-        try {
-            while (c.moveToNext()) {
-                String accountName = c.getString(0);
-                String accountType = c.getString(1);
-                if (TextUtils.isEmpty(accountName)) {
-                    continue;
-                }
-                Account account = new Account(accountName, accountType);
-                if (!accounts.containsKey(account)) {
-                    int numDeleted;
-                    numDeleted = db.delete(table, "_sync_account=? AND _sync_account_type=?",
-                            new String[]{account.name, account.type});
-                    if (Config.LOGV) {
-                        Log.v(TAG, "deleted " + numDeleted
-                                + " records from table " + table
-                                + " for account " + account);
-                    }
-                }
-            }
-        } finally {
-            c.close();
-        }
-    }
-
-    /**
-     * Called when the sync system determines that this provider should no longer
-     * contain records for the specified account.
-     */
-    public void wipeAccount(Account account) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        Map<String, String> tableMap = db.getSyncedTables();
-        ArrayList<String> tables = new ArrayList<String>();
-        tables.addAll(tableMap.keySet());
-        tables.addAll(tableMap.values());
-
-        db.beginTransaction();
-
-        try {
-            // remove the SyncState data
-            mSyncState.discardSyncData(db, account);
-
-            // remove the data in the synced tables
-            for (String table : tables) {
-                db.delete(table, SYNC_ACCOUNT_WHERE_CLAUSE,
-                        new String[]{account.name, account.type});
-            }
-            db.setTransactionSuccessful();
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    /**
-     * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
-     */
-    public byte[] readSyncDataBytes(Account account) {
-        return mSyncState.readSyncDataBytes(mOpenHelper.getReadableDatabase(), account);
-    }
-
-    /**
-     * Sets the SyncData bytes for the given account. The byte array may be null.
-     */
-    public void writeSyncDataBytes(Account account, byte[] data) {
-        mSyncState.writeSyncDataBytes(mOpenHelper.getWritableDatabase(), account, data);
-    }
-
-    protected ContentProvider getSyncStateProvider() {
-        return mSyncState.asContentProvider();
-    }
-}
diff --git a/core/java/android/content/AbstractTableMerger.java b/core/java/android/content/AbstractTableMerger.java
deleted file mode 100644
index 9545fd7f..0000000
--- a/core/java/android/content/AbstractTableMerger.java
+++ /dev/null
@@ -1,599 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.os.Debug;
-import android.provider.BaseColumns;
-import static android.provider.SyncConstValue.*;
-import android.text.TextUtils;
-import android.util.Log;
-import android.accounts.Account;
-
-/**
- * @hide
- */
-public abstract class AbstractTableMerger
-{
-    private ContentValues mValues;
-
-    protected SQLiteDatabase mDb;
-    protected String mTable;
-    protected Uri mTableURL;
-    protected String mDeletedTable;
-    protected Uri mDeletedTableURL;
-    static protected ContentValues mSyncMarkValues;
-    static private boolean TRACE;
-
-    static {
-        mSyncMarkValues = new ContentValues();
-        mSyncMarkValues.put(_SYNC_MARK, 1);
-        TRACE = false;
-    }
-
-    private static final String TAG = "AbstractTableMerger";
-    private static final String[] syncDirtyProjection =
-            new String[] {_SYNC_DIRTY, BaseColumns._ID, _SYNC_ID, _SYNC_VERSION};
-    private static final String[] syncIdAndVersionProjection =
-            new String[] {_SYNC_ID, _SYNC_VERSION};
-
-    private volatile boolean mIsMergeCancelled;
-
-    private static final String SELECT_MARKED = _SYNC_MARK + "> 0 and "
-            + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?";
-
-    private static final String SELECT_BY_SYNC_ID_AND_ACCOUNT =
-            _SYNC_ID +"=? and " + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?";
-    private static final String SELECT_BY_ID = BaseColumns._ID +"=?";
-
-    private static final String SELECT_UNSYNCED =
-            "(" + _SYNC_ACCOUNT + " IS NULL OR ("
-                + _SYNC_ACCOUNT + "=? and " + _SYNC_ACCOUNT_TYPE + "=?)) and "
-            + "(" + _SYNC_ID + " IS NULL OR (" + _SYNC_DIRTY + " > 0 and "
-                                              + _SYNC_VERSION + " IS NOT NULL))";
-
-    public AbstractTableMerger(SQLiteDatabase database,
-            String table, Uri tableURL, String deletedTable,
-            Uri deletedTableURL)
-    {
-        mDb = database;
-        mTable = table;
-        mTableURL = tableURL;
-        mDeletedTable = deletedTable;
-        mDeletedTableURL = deletedTableURL;
-        mValues = new ContentValues();
-    }
-
-    public abstract void insertRow(ContentProvider diffs,
-            Cursor diffsCursor);
-    public abstract void updateRow(long localPersonID,
-            ContentProvider diffs, Cursor diffsCursor);
-    public abstract void resolveRow(long localPersonID,
-            String syncID, ContentProvider diffs, Cursor diffsCursor);
-
-    /**
-     * This is called when it is determined that a row should be deleted from the
-     * ContentProvider. The localCursor is on a table from the local ContentProvider
-     * and its current position is of the row that should be deleted. The localCursor
-     * is only guaranteed to contain the BaseColumns.ID column so the implementation
-     * of deleteRow() must query the database directly if other columns are needed.
-     * <p>
-     * It is the responsibility of the implementation of this method to ensure that the cursor
-     * points to the next row when this method returns, either by calling Cursor.deleteRow() or
-     * Cursor.next().
-     *
-     * @param localCursor The Cursor into the local table, which points to the row that
-     *   is to be deleted.
-     */
-    public void deleteRow(Cursor localCursor) {
-        localCursor.deleteRow();
-    }
-
-    /**
-     * After {@link #merge} has completed, this method is called to send
-     * notifications to {@link android.database.ContentObserver}s of changes
-     * to the containing {@link ContentProvider}.  These notifications likely
-     * do not want to request a sync back to the network.
-     */
-    protected abstract void notifyChanges();
-
-    private static boolean findInCursor(Cursor cursor, int column, String id) {
-        while (!cursor.isAfterLast() && !cursor.isNull(column)) {
-            int comp = id.compareTo(cursor.getString(column));
-            if (comp > 0) {
-                cursor.moveToNext();
-                continue;
-            }
-            return comp == 0;
-        }
-        return false;
-    }
-
-    public void onMergeCancelled() {
-        mIsMergeCancelled = true;
-    }
-
-    /**
-     * Carry out a merge of the given diffs, and add the results to
-     * the given MergeResult.  If we are the first merge to find
-     * client-side diffs, we'll use the given ContentProvider to
-     * construct a temporary instance to hold them.
-     */
-    public void merge(final SyncContext context,
-            final Account account,
-            final SyncableContentProvider serverDiffs,
-            TempProviderSyncResult result,
-            SyncResult syncResult, SyncableContentProvider temporaryInstanceFactory) {
-        mIsMergeCancelled = false;
-        if (serverDiffs != null) {
-            if (!mDb.isDbLockedByCurrentThread()) {
-                throw new IllegalStateException("this must be called from within a DB transaction");
-            }
-            mergeServerDiffs(context, account, serverDiffs, syncResult);
-            notifyChanges();
-        }
-
-        if (result != null) {
-            findLocalChanges(result, temporaryInstanceFactory, account, syncResult);
-        }
-        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "merge complete");
-    }
-
-    /**
-     * @hide this is public for testing purposes only
-     */
-    public void mergeServerDiffs(SyncContext context,
-            Account account, SyncableContentProvider serverDiffs, SyncResult syncResult) {
-        boolean diffsArePartial = serverDiffs.getContainsDiffs();
-        // mark the current rows so that we can distinguish these from new
-        // inserts that occur during the merge
-        mDb.update(mTable, mSyncMarkValues, null, null);
-        if (mDeletedTable != null) {
-            mDb.update(mDeletedTable, mSyncMarkValues, null, null);
-        }
-
-        Cursor localCursor = null;
-        Cursor deletedCursor = null;
-        Cursor diffsCursor = null;
-        try {
-            // load the local database entries, so we can merge them with the server
-            final String[] accountSelectionArgs = new String[]{account.name, account.type};
-            localCursor = mDb.query(mTable, syncDirtyProjection,
-                    SELECT_MARKED, accountSelectionArgs, null, null,
-                    mTable + "." + _SYNC_ID);
-            if (mDeletedTable != null) {
-                deletedCursor = mDb.query(mDeletedTable, syncIdAndVersionProjection,
-                        SELECT_MARKED, accountSelectionArgs, null, null,
-                        mDeletedTable + "." + _SYNC_ID);
-            } else {
-                deletedCursor =
-                        mDb.rawQuery("select 'a' as _sync_id, 'b' as _sync_version limit 0", null);
-            }
-
-            // Apply updates and insertions from the server
-            diffsCursor = serverDiffs.query(mTableURL,
-                    null, null, null, mTable + "." + _SYNC_ID);
-            int deletedSyncIDColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_ID);
-            int deletedSyncVersionColumn = deletedCursor.getColumnIndexOrThrow(_SYNC_VERSION);
-            int serverSyncIDColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
-            int serverSyncVersionColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_VERSION);
-            int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);
-
-            String lastSyncId = null;
-            int diffsCount = 0;
-            int localCount = 0;
-            localCursor.moveToFirst();
-            deletedCursor.moveToFirst();
-            while (diffsCursor.moveToNext()) {
-                if (mIsMergeCancelled) {
-                    return;
-                }
-                mDb.yieldIfContended();
-                String serverSyncId = diffsCursor.getString(serverSyncIDColumn);
-                String serverSyncVersion = diffsCursor.getString(serverSyncVersionColumn);
-                long localRowId = 0;
-                String localSyncVersion = null;
-
-                diffsCount++;
-                context.setStatusText("Processing " + diffsCount + "/"
-                        + diffsCursor.getCount());
-                if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "processing server entry " +
-                        diffsCount + ", " + serverSyncId);
-
-                if (TRACE) {
-                    if (diffsCount == 10) {
-                        Debug.startMethodTracing("atmtrace");
-                    }
-                    if (diffsCount == 20) {
-                        Debug.stopMethodTracing();
-                    }
-                }
-
-                boolean conflict = false;
-                boolean update = false;
-                boolean insert = false;
-
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "found event with serverSyncID " + serverSyncId);
-                }
-                if (TextUtils.isEmpty(serverSyncId)) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.e(TAG, "server entry doesn't have a serverSyncID");
-                    }
-                    continue;
-                }
-
-                // It is possible that the sync adapter wrote the same record multiple times,
-                // e.g. if the same record came via multiple feeds. If this happens just ignore
-                // the duplicate records.
-                if (serverSyncId.equals(lastSyncId)) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "skipping record with duplicate remote server id " + lastSyncId);
-                    }
-                    continue;
-                }
-                lastSyncId = serverSyncId;
-
-                String localSyncID = null;
-                boolean localSyncDirty = false;
-
-                while (!localCursor.isAfterLast()) {
-                    if (mIsMergeCancelled) {
-                        return;
-                    }
-                    localCount++;
-                    localSyncID = localCursor.getString(2);
-
-                    // If the local record doesn't have a _sync_id then
-                    // it is new. Ignore it for now, we will send an insert
-                    // the the server later.
-                    if (TextUtils.isEmpty(localSyncID)) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "local record " +
-                                    localCursor.getLong(1) +
-                                    " has no _sync_id, ignoring");
-                        }
-                        localCursor.moveToNext();
-                        localSyncID = null;
-                        continue;
-                    }
-
-                    int comp = serverSyncId.compareTo(localSyncID);
-
-                    // the local DB has a record that the server doesn't have
-                    if (comp > 0) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "local record " +
-                                    localCursor.getLong(1) +
-                                    " has _sync_id " + localSyncID +
-                                    " that is < server _sync_id " + serverSyncId);
-                        }
-                        if (diffsArePartial) {
-                            localCursor.moveToNext();
-                        } else {
-                            deleteRow(localCursor);
-                            if (mDeletedTable != null) {
-                                mDb.delete(mDeletedTable, _SYNC_ID +"=?", new String[] {localSyncID});
-                            }
-                            syncResult.stats.numDeletes++;
-                            mDb.yieldIfContended();
-                        }
-                        localSyncID = null;
-                        continue;
-                    }
-
-                    // the server has a record that the local DB doesn't have
-                    if (comp < 0) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "local record " +
-                                    localCursor.getLong(1) +
-                                    " has _sync_id " + localSyncID +
-                                    " that is > server _sync_id " + serverSyncId);
-                        }
-                        localSyncID = null;
-                    }
-
-                    // the server and the local DB both have this record
-                    if (comp == 0) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "local record " +
-                                    localCursor.getLong(1) +
-                                    " has _sync_id " + localSyncID +
-                                    " that matches the server _sync_id");
-                        }
-                        localSyncDirty = localCursor.getInt(0) != 0;
-                        localRowId = localCursor.getLong(1);
-                        localSyncVersion = localCursor.getString(3);
-                        localCursor.moveToNext();
-                    }
-
-                    break;
-                }
-
-                // If this record is in the deleted table then update the server version
-                // in the deleted table, if necessary, and then ignore it here.
-                // We will send a deletion indication to the server down a
-                // little further.
-                if (findInCursor(deletedCursor, deletedSyncIDColumn, serverSyncId)) {
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "remote record " + serverSyncId + " is in the deleted table");
-                    }
-                    final String deletedSyncVersion = deletedCursor.getString(deletedSyncVersionColumn);
-                    if (!TextUtils.equals(deletedSyncVersion, serverSyncVersion)) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "setting version of deleted record " + serverSyncId + " to "
-                                    + serverSyncVersion);
-                        }
-                        ContentValues values = new ContentValues();
-                        values.put(_SYNC_VERSION, serverSyncVersion);
-                        mDb.update(mDeletedTable, values, "_sync_id=?", new String[]{serverSyncId});
-                    }
-                    continue;
-                }
-
-                // If the _sync_local_id is present in the diffsCursor
-                // then this record corresponds to a local record that was just
-                // inserted into the server and the _sync_local_id is the row id
-                // of the local record. Set these fields so that the next check
-                // treats this record as an update, which will allow the
-                // merger to update the record with the server's sync id
-                if (!diffsCursor.isNull(serverSyncLocalIdColumn)) {
-                    localRowId = diffsCursor.getLong(serverSyncLocalIdColumn);
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "the remote record with sync id " + serverSyncId
-                                + " has a local sync id, " + localRowId);
-                    }
-                    localSyncID = serverSyncId;
-                    localSyncDirty = false;
-                    localSyncVersion = null;
-                }
-
-                if (!TextUtils.isEmpty(localSyncID)) {
-                    // An existing server item has changed
-                    // If serverSyncVersion is null, there is no edit URL;
-                    // server won't let this change be written.
-                    boolean recordChanged = (localSyncVersion == null) ||
-                            (serverSyncVersion == null) ||
-                            !serverSyncVersion.equals(localSyncVersion);
-                    if (recordChanged) {
-                        if (localSyncDirty) {
-                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                                Log.v(TAG, "remote record " + serverSyncId
-                                        + " conflicts with local _sync_id " + localSyncID
-                                        + ", local _id " + localRowId);
-                            }
-                            conflict = true;
-                        } else {
-                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                                Log.v(TAG,
-                                        "remote record " +
-                                                serverSyncId +
-                                                " updates local _sync_id " +
-                                                localSyncID + ", local _id " +
-                                                localRowId);
-                            }
-                            update = true;
-                        }
-                    } else {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG,
-                                    "Skipping update: localSyncVersion: " + localSyncVersion +
-                                    ", serverSyncVersion: " + serverSyncVersion);
-                        }
-                    }
-                } else {
-                    // the local db doesn't know about this record so add it
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "remote record " + serverSyncId + " is new, inserting");
-                    }
-                    insert = true;
-                }
-
-                if (update) {
-                    updateRow(localRowId, serverDiffs, diffsCursor);
-                    syncResult.stats.numUpdates++;
-                } else if (conflict) {
-                    resolveRow(localRowId, serverSyncId, serverDiffs, diffsCursor);
-                    syncResult.stats.numUpdates++;
-                } else if (insert) {
-                    insertRow(serverDiffs, diffsCursor);
-                    syncResult.stats.numInserts++;
-                }
-            }
-
-            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                Log.v(TAG, "processed " + diffsCount + " server entries");
-            }
-
-            // If tombstones aren't in use delete any remaining local rows that
-            // don't have corresponding server rows. Keep the rows that don't
-            // have a sync id since those were created locally and haven't been
-            // synced to the server yet.
-            if (!diffsArePartial) {
-                while (!localCursor.isAfterLast() && !TextUtils.isEmpty(localCursor.getString(2))) {
-                    if (mIsMergeCancelled) {
-                        return;
-                    }
-                    localCount++;
-                    final String localSyncId = localCursor.getString(2);
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG,
-                                "deleting local record " +
-                                        localCursor.getLong(1) +
-                                        " _sync_id " + localSyncId);
-                    }
-                    deleteRow(localCursor);
-                    if (mDeletedTable != null) {
-                        mDb.delete(mDeletedTable, _SYNC_ID + "=?", new String[] {localSyncId});
-                    }
-                    syncResult.stats.numDeletes++;
-                    mDb.yieldIfContended();
-                }
-            }
-            if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "checked " + localCount +
-                    " local entries");
-        } finally {
-            if (diffsCursor != null) diffsCursor.close();
-            if (localCursor != null) localCursor.close();
-            if (deletedCursor != null) deletedCursor.close();
-        }
-
-
-        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "applying deletions from the server");
-
-        // Apply deletions from the server
-        if (mDeletedTableURL != null) {
-            diffsCursor = serverDiffs.query(mDeletedTableURL, null, null, null, null);
-            try {
-                while (diffsCursor.moveToNext()) {
-                    if (mIsMergeCancelled) {
-                        return;
-                    }
-                    // delete all rows that match each element in the diffsCursor
-                    fullyDeleteMatchingRows(diffsCursor, account, syncResult);
-                    mDb.yieldIfContended();
-                }
-            } finally {
-                diffsCursor.close();
-            }
-        }
-    }
-
-    private void fullyDeleteMatchingRows(Cursor diffsCursor, Account account,
-            SyncResult syncResult) {
-        int serverSyncIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_ID);
-        final boolean deleteBySyncId = !diffsCursor.isNull(serverSyncIdColumn);
-
-        // delete the rows explicitly so that the delete operation can be overridden
-        final String[] selectionArgs;
-        Cursor c = null;
-        try {
-            if (deleteBySyncId) {
-                selectionArgs = new String[]{diffsCursor.getString(serverSyncIdColumn),
-                        account.name, account.type};
-                c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_SYNC_ID_AND_ACCOUNT,
-                        selectionArgs, null, null, null);
-            } else {
-                int serverSyncLocalIdColumn = diffsCursor.getColumnIndexOrThrow(_SYNC_LOCAL_ID);
-                selectionArgs = new String[]{diffsCursor.getString(serverSyncLocalIdColumn)};
-                c = mDb.query(mTable, new String[]{BaseColumns._ID}, SELECT_BY_ID, selectionArgs,
-                        null, null, null);
-            }
-            c.moveToFirst();
-            while (!c.isAfterLast()) {
-                deleteRow(c); // advances the cursor
-                syncResult.stats.numDeletes++;
-            }
-        } finally {
-          if (c != null) c.close();
-        }
-        if (deleteBySyncId && mDeletedTable != null) {
-            mDb.delete(mDeletedTable, SELECT_BY_SYNC_ID_AND_ACCOUNT, selectionArgs);
-        }
-    }
-
-    /**
-     * Converts cursor into a Map, using the correct types for the values.
-     */
-    protected void cursorRowToContentValues(Cursor cursor, ContentValues map) {
-        DatabaseUtils.cursorRowToContentValues(cursor, map);
-    }
-
-    /**
-     * Finds local changes, placing the results in the given result object.
-     * @param temporaryInstanceFactory As an optimization for the case
-     * where there are no client-side diffs, mergeResult may initially
-     * have no {@link TempProviderSyncResult#tempContentProvider}.  If this is
-     * the first in the sequence of AbstractTableMergers to find
-     * client-side diffs, it will use the given ContentProvider to
-     * create a temporary instance and store its {@link
-     * android.content.ContentProvider} in the mergeResult.
-     * @param account
-     * @param syncResult
-     */
-    private void findLocalChanges(TempProviderSyncResult mergeResult,
-            SyncableContentProvider temporaryInstanceFactory, Account account,
-            SyncResult syncResult) {
-        SyncableContentProvider clientDiffs = mergeResult.tempContentProvider;
-        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client updates");
-
-        final String[] accountSelectionArgs = new String[]{account.name, account.type};
-
-        // Generate the client updates and insertions
-        // Create a cursor for dirty records
-        long numInsertsOrUpdates = 0;
-        Cursor localChangesCursor = mDb.query(mTable, null, SELECT_UNSYNCED, accountSelectionArgs,
-                null, null, null);
-        try {
-            numInsertsOrUpdates = localChangesCursor.getCount();
-            while (localChangesCursor.moveToNext()) {
-                if (mIsMergeCancelled) {
-                    return;
-                }
-                if (clientDiffs == null) {
-                    clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
-                }
-                mValues.clear();
-                cursorRowToContentValues(localChangesCursor, mValues);
-                mValues.remove("_id");
-                DatabaseUtils.cursorLongToContentValues(localChangesCursor, "_id", mValues,
-                        _SYNC_LOCAL_ID);
-                clientDiffs.insert(mTableURL, mValues);
-            }
-        } finally {
-          localChangesCursor.close();
-        }
-
-        // Generate the client deletions
-        if (Log.isLoggable(TAG, Log.VERBOSE)) Log.v(TAG, "generating client deletions");
-        long numEntries = DatabaseUtils.queryNumEntries(mDb, mTable);
-        long numDeletedEntries = 0;
-        if (mDeletedTable != null) {
-            Cursor deletedCursor = mDb.query(mDeletedTable,
-                    syncIdAndVersionProjection,
-                    _SYNC_ACCOUNT + "=? AND " + _SYNC_ACCOUNT_TYPE + "=? AND "
-                            + _SYNC_ID + " IS NOT NULL", accountSelectionArgs,
-                    null, null, mDeletedTable + "." + _SYNC_ID);
-            try {
-                numDeletedEntries = deletedCursor.getCount();
-                while (deletedCursor.moveToNext()) {
-                    if (mIsMergeCancelled) {
-                        return;
-                    }
-                    if (clientDiffs == null) {
-                        clientDiffs = temporaryInstanceFactory.getTemporaryInstance();
-                    }
-                    mValues.clear();
-                    DatabaseUtils.cursorRowToContentValues(deletedCursor, mValues);
-                    clientDiffs.insert(mDeletedTableURL, mValues);
-                }
-            } finally {
-                deletedCursor.close();
-            }
-        }
-
-        if (clientDiffs != null) {
-            mergeResult.tempContentProvider = clientDiffs;
-        }
-        syncResult.stats.numDeletes += numDeletedEntries;
-        syncResult.stats.numUpdates += numInsertsOrUpdates;
-        syncResult.stats.numEntries += numEntries;
-    }
-}
diff --git a/core/java/android/content/AbstractThreadedSyncAdapter.java b/core/java/android/content/AbstractThreadedSyncAdapter.java
index 154c4a6..14bc5dd 100644
--- a/core/java/android/content/AbstractThreadedSyncAdapter.java
+++ b/core/java/android/content/AbstractThreadedSyncAdapter.java
@@ -117,7 +117,7 @@
                 if (mSyncThread != null
                         && mSyncThread.mSyncContext.getSyncContextBinder()
                         == syncContext.asBinder()) {
-                    mSyncThread.interrupt();
+                    onSyncCanceled(mSyncThread);
                 }
             }
         }
@@ -207,4 +207,15 @@
      */
     public abstract void onPerformSync(Account account, Bundle extras,
             String authority, ContentProviderClient provider, SyncResult syncResult);
+
+    /**
+     * Indicates that a sync operation has been canceled. This will be invoked on a separate
+     * thread than the sync thread and so you must consider the multi-threaded implications
+     * of the work that you do in this method.
+     *
+     * @param thread the thread that is running the sync operation to cancel
+     */
+    public void onSyncCanceled(Thread thread) {
+        thread.interrupt();
+    }
 }
diff --git a/core/java/android/content/SyncAdapter.java b/core/java/android/content/SyncAdapter.java
deleted file mode 100644
index a5afe87..0000000
--- a/core/java/android/content/SyncAdapter.java
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.content;
-
-import android.os.Bundle;
-import android.os.RemoteException;
-import android.accounts.Account;
-
-/**
- * @hide
- */
-public abstract class SyncAdapter {
-    private static final String TAG = "SyncAdapter";
-
-    /** Kernel event log tag. */
-    public static final int LOG_SYNC_DETAILS = EventLogTags.SYNC_DETAILS;
-
-    class Transport extends ISyncAdapter.Stub {
-        public void startSync(ISyncContext syncContext, String authority, Account account,
-                Bundle extras) throws RemoteException {
-            SyncAdapter.this.startSync(new SyncContext(syncContext), account, authority, extras);
-        }
-
-        public void cancelSync(ISyncContext syncContext) throws RemoteException {
-            SyncAdapter.this.cancelSync();
-        }
-
-        public void initialize(Account account, String authority) throws RemoteException {
-            Bundle extras = new Bundle();
-            extras.putBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, true);
-            startSync(null, authority, account, extras);
-        }
-    }
-
-    Transport mTransport = new Transport();
-
-    /**
-     * Get the Transport object.
-     */
-    public final ISyncAdapter getISyncAdapter()
-    {
-        return mTransport;
-    }
-
-    /**
-     * Initiate a sync for this account. SyncAdapter-specific parameters may
-     * be specified in extras, which is guaranteed to not be null. IPC invocations
-     * of this method and cancelSync() are guaranteed to be serialized.
-     *
-     * @param syncContext the ISyncContext used to indicate the progress of the sync. When
-     *   the sync is finished (successfully or not) ISyncContext.onFinished() must be called.
-     * @param account the account that should be synced
-     * @param authority the authority if the sync request
-     * @param extras SyncAdapter-specific parameters
-     */
-    public abstract void startSync(SyncContext syncContext, Account account, String authority, 
-            Bundle extras);
-
-    /**
-     * Cancel the most recently initiated sync. Due to race conditions, this may arrive
-     * after the ISyncContext.onFinished() for that sync was called. IPC invocations
-     * of this method and startSync() are guaranteed to be serialized.
-     */
-    public abstract void cancelSync();
-}
diff --git a/core/java/android/content/SyncStateContentProviderHelper.java b/core/java/android/content/SyncStateContentProviderHelper.java
deleted file mode 100644
index 64bbe25..0000000
--- a/core/java/android/content/SyncStateContentProviderHelper.java
+++ /dev/null
@@ -1,243 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.content;
-
-import com.android.internal.util.ArrayUtils;
-
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-import android.accounts.Account;
-
-/**
- * Extends the schema of a ContentProvider to include the _sync_state table
- * and implements query/insert/update/delete to access that table using the
- * authority "syncstate". This can be used to store the sync state for a
- * set of accounts.
- * 
- * @hide
- */
-public class SyncStateContentProviderHelper {
-    final SQLiteOpenHelper mOpenHelper;
-
-    private static final String SYNC_STATE_AUTHORITY = "syncstate";
-    private static final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
-    private static final int STATE = 0;
-
-    private static final Uri CONTENT_URI =
-            Uri.parse("content://" + SYNC_STATE_AUTHORITY + "/state");
-
-    private static final String ACCOUNT_WHERE = "_sync_account = ? AND _sync_account_type = ?";
-
-    private final Provider mInternalProviderInterface;
-
-    private static final String SYNC_STATE_TABLE = "_sync_state";
-    private static long DB_VERSION = 3;
-
-    private static final String[] ACCOUNT_PROJECTION =
-            new String[]{"_sync_account", "_sync_account_type"};
-
-    static {
-        sURIMatcher.addURI(SYNC_STATE_AUTHORITY, "state", STATE);
-    }
-
-    public SyncStateContentProviderHelper(SQLiteOpenHelper openHelper) {
-        mOpenHelper = openHelper;
-        mInternalProviderInterface = new Provider();
-    }
-
-    public ContentProvider asContentProvider() {
-        return mInternalProviderInterface;
-    }
-
-    public void createDatabase(SQLiteDatabase db) {
-        db.execSQL("DROP TABLE IF EXISTS _sync_state");
-        db.execSQL("CREATE TABLE _sync_state (" +
-                   "_id INTEGER PRIMARY KEY," +
-                   "_sync_account TEXT," +
-                   "_sync_account_type TEXT," +
-                   "data TEXT," +
-                   "UNIQUE(_sync_account, _sync_account_type)" +
-                   ");");
-
-        db.execSQL("DROP TABLE IF EXISTS _sync_state_metadata");
-        db.execSQL("CREATE TABLE _sync_state_metadata (" +
-                    "version INTEGER" +
-                    ");");
-        ContentValues values = new ContentValues();
-        values.put("version", DB_VERSION);
-        db.insert("_sync_state_metadata", "version", values);
-    }
-
-    protected void onDatabaseOpened(SQLiteDatabase db) {
-        long version = DatabaseUtils.longForQuery(db,
-                "select version from _sync_state_metadata", null);
-        if (version != DB_VERSION) {
-            createDatabase(db);
-        }
-    }
-
-    class Provider extends ContentProvider {
-        public boolean onCreate() {
-            throw new UnsupportedOperationException("not implemented");
-        }
-
-        public Cursor query(Uri url, String[] projection, String selection, String[] selectionArgs,
-                String sortOrder) {
-            SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-            int match = sURIMatcher.match(url);
-            switch (match) {
-                case STATE:
-                    return db.query(SYNC_STATE_TABLE, projection, selection, selectionArgs,
-                            null, null, sortOrder);
-                default:
-                    throw new UnsupportedOperationException("Cannot query URL: " + url);
-            }
-        }
-
-        public String getType(Uri uri) {
-            throw new UnsupportedOperationException("not implemented");
-        }
-
-        public Uri insert(Uri url, ContentValues values) {
-            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            int match = sURIMatcher.match(url);
-            switch (match) {
-                case STATE: {
-                    long id = db.insert(SYNC_STATE_TABLE, "feed", values);
-                    return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
-                }
-                default:
-                    throw new UnsupportedOperationException("Cannot insert into URL: " + url);
-            }
-        }
-
-        public int delete(Uri url, String userWhere, String[] whereArgs) {
-            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            switch (sURIMatcher.match(url)) {
-                case STATE:
-                    return db.delete(SYNC_STATE_TABLE, userWhere, whereArgs);
-                default:
-                    throw new IllegalArgumentException("Unknown URL " + url);
-            }
-
-        }
-
-        public int update(Uri url, ContentValues values, String selection, String[] selectionArgs) {
-            SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-            switch (sURIMatcher.match(url)) {
-                case STATE:
-                    return db.update(SYNC_STATE_TABLE, values, selection, selectionArgs);
-                default:
-                    throw new UnsupportedOperationException("Cannot update URL: " + url);
-            }
-
-        }
-    }
-
-    /**
-     * Check if the url matches content that this ContentProvider manages.
-     * @param url the Uri to check
-     * @return true if this ContentProvider can handle that Uri.
-     */
-    public boolean matches(Uri url) {
-        return (SYNC_STATE_AUTHORITY.equals(url.getAuthority()));
-    }
-
-    /**
-     * Replaces the contents of the _sync_state table in the destination ContentProvider
-     * with the row that matches account, if any, in the source ContentProvider.
-     * <p>
-     * The ContentProviders must expose the _sync_state table as URI content://syncstate/state.
-     * @param dbSrc the database to read from
-     * @param dbDest the database to write to
-     * @param account the account of the row that should be copied over.
-     */
-    public void copySyncState(SQLiteDatabase dbSrc, SQLiteDatabase dbDest,
-            Account account) {
-        final String[] whereArgs = new String[]{account.name, account.type};
-        Cursor c = dbSrc.query(SYNC_STATE_TABLE,
-                new String[]{"_sync_account", "_sync_account_type", "data"},
-                ACCOUNT_WHERE, whereArgs, null, null, null);
-        try {
-            if (c.moveToNext()) {
-                ContentValues values = new ContentValues();
-                values.put("_sync_account", c.getString(0));
-                values.put("_sync_account_type", c.getString(1));
-                values.put("data", c.getBlob(2));
-                dbDest.replace(SYNC_STATE_TABLE, "_sync_account", values);
-            }
-        } finally {
-            c.close();
-        }
-    }
-
-    public void onAccountsChanged(Account[] accounts) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        Cursor c = db.query(SYNC_STATE_TABLE, ACCOUNT_PROJECTION, null, null, null, null, null);
-        try {
-            while (c.moveToNext()) {
-                final String accountName = c.getString(0);
-                final String accountType = c.getString(1);
-                Account account = new Account(accountName, accountType);
-                if (!ArrayUtils.contains(accounts, account)) {
-                    db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE,
-                            new String[]{accountName, accountType});
-                }
-            }
-        } finally {
-            c.close();
-        }
-    }
-
-    public void discardSyncData(SQLiteDatabase db, Account account) {
-        if (account != null) {
-            db.delete(SYNC_STATE_TABLE, ACCOUNT_WHERE, new String[]{account.name, account.type});
-        } else {
-            db.delete(SYNC_STATE_TABLE, null, null);
-        }
-    }
-
-    /**
-     * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
-     */
-    public byte[] readSyncDataBytes(SQLiteDatabase db, Account account) {
-        Cursor c = db.query(SYNC_STATE_TABLE, null, ACCOUNT_WHERE,
-                new String[]{account.name, account.type}, null, null, null);
-        try {
-            if (c.moveToFirst()) {
-                return c.getBlob(c.getColumnIndexOrThrow("data"));
-            }
-        } finally {
-            c.close();
-        }
-        return null;
-    }
-
-    /**
-     * Sets the SyncData bytes for the given account. The bytes array may be null.
-     */
-    public void writeSyncDataBytes(SQLiteDatabase db, Account account, byte[] data) {
-        ContentValues values = new ContentValues();
-        values.put("data", data);
-        db.update(SYNC_STATE_TABLE, values, ACCOUNT_WHERE,
-                new String[]{account.name, account.type});
-    }
-}
diff --git a/core/java/android/content/SyncableContentProvider.java b/core/java/android/content/SyncableContentProvider.java
deleted file mode 100644
index ab4e91c..0000000
--- a/core/java/android/content/SyncableContentProvider.java
+++ /dev/null
@@ -1,237 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.content;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.accounts.Account;
-
-import java.util.Map;
-
-/**
- * A specialization of the ContentProvider that centralizes functionality
- * used by ContentProviders that are syncable. It also wraps calls to the ContentProvider
- * inside of database transactions.
- *
- * @hide
- */
-public abstract class SyncableContentProvider extends ContentProvider {
-    protected abstract boolean isTemporary();
-
-    private volatile TempProviderSyncAdapter mTempProviderSyncAdapter;
-
-    public void setTempProviderSyncAdapter(TempProviderSyncAdapter syncAdapter) {
-        mTempProviderSyncAdapter = syncAdapter;
-    }
-
-    public TempProviderSyncAdapter getTempProviderSyncAdapter() {
-        return mTempProviderSyncAdapter;
-    }
-
-    /**
-     * Close resources that must be closed. You must call this to properly release
-     * the resources used by the SyncableContentProvider.
-     */
-    public abstract void close();
-
-    /**
-     * Override to create your schema and do anything else you need to do with a new database.
-     * This is run inside a transaction (so you don't need to use one).
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     */
-    protected abstract void bootstrapDatabase(SQLiteDatabase db);
-
-    /**
-     * Override to upgrade your database from an old version to the version you specified.
-     * Don't set the DB version, this will automatically be done after the method returns.
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     *
-     * @param oldVersion version of the existing database
-     * @param newVersion current version to upgrade to
-     * @return true if the upgrade was lossless, false if it was lossy
-     */
-    protected abstract boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion);
-
-    /**
-     * Override to do anything (like cleanups or checks) you need to do after opening a database.
-     * Does nothing by default.  This is run inside a transaction (so you don't need to use one).
-     * This method may not use getDatabase(), or call content provider methods, it must only
-     * use the database handle passed to it.
-     */
-    protected abstract void onDatabaseOpened(SQLiteDatabase db);
-
-    /**
-     * Get a non-persistent instance of this content provider.
-     * You must call {@link #close} on the returned
-     * SyncableContentProvider when you are done with it.
-     *
-     * @return a non-persistent content provider with the same layout as this
-     * provider.
-     */
-    public abstract SyncableContentProvider getTemporaryInstance();
-
-    public abstract SQLiteDatabase getDatabase();
-
-    public abstract boolean getContainsDiffs();
-
-    public abstract void setContainsDiffs(boolean containsDiffs);
-
-    /**
-     * Each subclass of this class should define a subclass of {@link
-     * AbstractTableMerger} for each table they wish to merge.  It
-     * should then override this method and return one instance of
-     * each merger, in sequence.  Their {@link
-     * AbstractTableMerger#merge merge} methods will be called, one at a
-     * time, in the order supplied.
-     *
-     * <p>The default implementation returns an empty list, so that no
-     * merging will occur.
-     * @return A sequence of subclasses of {@link
-     * AbstractTableMerger}, one for each table that should be merged.
-     */
-    protected abstract Iterable<? extends AbstractTableMerger> getMergers();
-
-    /**
-     * Check if changes to this URI can be syncable changes.
-     * @param uri the URI of the resource that was changed
-     * @return true if changes to this URI can be syncable changes, false otherwise
-     */
-    public abstract boolean changeRequiresLocalSync(Uri uri);
-
-    /**
-     * Called right before a sync is started.
-     *
-     * @param context the sync context for the operation
-     * @param account
-     */
-    public abstract void onSyncStart(SyncContext context, Account account);
-
-    /**
-     * Called right after a sync is completed
-     *
-     * @param context the sync context for the operation
-     * @param success true if the sync succeeded, false if an error occurred
-     */
-    public abstract void onSyncStop(SyncContext context, boolean success);
-
-    /**
-     * The account of the most recent call to onSyncStart()
-     * @return the account
-     */
-    public abstract Account getSyncingAccount();
-
-    /**
-     * Merge diffs from a sync source with this content provider.
-     *
-     * @param context the SyncContext within which this merge is taking place
-     * @param diffs A temporary content provider containing diffs from a sync
-     *   source.
-     * @param result a MergeResult that contains information about the merge, including
-     *   a temporary content provider with the same layout as this provider containing
-     * @param syncResult
-     */
-    public abstract void merge(SyncContext context, SyncableContentProvider diffs,
-            TempProviderSyncResult result, SyncResult syncResult);
-
-
-    /**
-     * Invoked when the active sync has been canceled. The default
-     * implementation doesn't do anything (except ensure that this
-     * provider is syncable). Subclasses of ContentProvider
-     * that support canceling of sync should override this.
-     */
-    public abstract void onSyncCanceled();
-
-
-    public abstract boolean isMergeCancelled();
-
-    /**
-     * Subclasses should override this instead of update(). See update()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract int updateInternal(Uri url, ContentValues values,
-            String selection, String[] selectionArgs);
-
-    /**
-     * Subclasses should override this instead of delete(). See delete()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract int deleteInternal(Uri url, String selection, String[] selectionArgs);
-
-    /**
-     * Subclasses should override this instead of insert(). See insert()
-     * for details.
-     *
-     * <p> This method is called within a acquireDbLock()/releaseDbLock() block,
-     * which means a database transaction will be active during the call;
-     */
-    protected abstract Uri insertInternal(Uri url, ContentValues values);
-
-    /**
-     * Subclasses should override this instead of query(). See query()
-     * for details.
-     *
-     * <p> This method is *not* called within a acquireDbLock()/releaseDbLock()
-     * block for performance reasons. If an implementation needs atomic access
-     * to the database the lock can be acquired then.
-     */
-    protected abstract Cursor queryInternal(Uri url, String[] projection,
-            String selection, String[] selectionArgs, String sortOrder);
-
-    /**
-     * Make sure that there are no entries for accounts that no longer exist
-     * @param accountsArray the array of currently-existing accounts
-     */
-    protected abstract void onAccountsChanged(Account[] accountsArray);
-
-    /**
-     * A helper method to delete all rows whose account is not in the accounts
-     * map. The accountColumnName is the name of the column that is expected
-     * to hold the account. If a row has an empty account it is never deleted.
-     *
-     * @param accounts a map of existing accounts
-     * @param table the table to delete from
-     */
-    protected abstract void deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts,
-            String table);
-
-    /**
-     * Called when the sync system determines that this provider should no longer
-     * contain records for the specified account.
-     */
-    public abstract void wipeAccount(Account account);
-
-    /**
-     * Retrieves the SyncData bytes for the given account. The byte array returned may be null.
-     */
-    public abstract byte[] readSyncDataBytes(Account account);
-
-    /**
-     * Sets the SyncData bytes for the given account. The bytes array may be null.
-     */
-    public abstract void writeSyncDataBytes(Account account, byte[] data);
-}
-
diff --git a/core/java/android/content/TempProviderSyncAdapter.java b/core/java/android/content/TempProviderSyncAdapter.java
deleted file mode 100644
index 5ccaa26..0000000
--- a/core/java/android/content/TempProviderSyncAdapter.java
+++ /dev/null
@@ -1,585 +0,0 @@
-package android.content;
-
-import android.accounts.Account;
-import android.accounts.AuthenticatorException;
-import android.accounts.OperationCanceledException;
-import android.database.SQLException;
-import android.net.TrafficStats;
-import android.os.Bundle;
-import android.os.Debug;
-import android.os.Parcelable;
-import android.os.Process;
-import android.os.SystemProperties;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.EventLog;
-import android.util.Log;
-import android.util.TimingLogger;
-
-import java.io.IOException;
-
-/**
- * @hide
- */
-public abstract class TempProviderSyncAdapter extends SyncAdapter {
-    private static final String TAG = "Sync";
-
-    private static final int MAX_GET_SERVER_DIFFS_LOOP_COUNT = 20;
-    private static final int MAX_UPLOAD_CHANGES_LOOP_COUNT = 10;
-    private static final int NUM_ALLOWED_SIMULTANEOUS_DELETIONS = 5;
-    private static final long PERCENT_ALLOWED_SIMULTANEOUS_DELETIONS = 20;
-
-    private volatile SyncableContentProvider mProvider;
-    private volatile SyncThread mSyncThread = null;
-    private volatile boolean mProviderSyncStarted;
-    private volatile boolean mAdapterSyncStarted;
-    
-    public TempProviderSyncAdapter(SyncableContentProvider provider) {
-        super();
-        mProvider = provider;
-    }
-
-    /**
-     * Used by getServerDiffs() to track the sync progress for a given
-     * sync adapter. Implementations of SyncAdapter generally specialize
-     * this class in order to track specific data about that SyncAdapter's
-     * sync. If an implementation of SyncAdapter doesn't need to store
-     * any data for a sync it may use TrivialSyncData.
-     */
-    public static abstract class SyncData implements Parcelable {
-
-    }
-
-    public final void setContext(Context context) {
-        mContext = context;
-    }
-
-    /**
-     * Retrieve the Context this adapter is running in.  Only available
-     * once onSyncStarting() is called (not available from constructor).
-     */
-    final public Context getContext() {
-        return mContext;
-    }
-
-    /**
-     * Called right before a sync is started.
-     *
-     * @param context allows you to publish status and interact with the
-     * @param account the account to sync
-     * @param manualSync true if this sync was requested manually by the user
-     * @param result information to track what happened during this sync attempt
-     */
-    public abstract void onSyncStarting(SyncContext context, Account account, boolean manualSync,
-            SyncResult result);
-
-    /**
-     * Called right after a sync is completed
-     *
-     * @param context allows you to publish status and interact with the
-     *                user during interactive syncs.
-     * @param success true if the sync suceeded, false if an error occured
-     */
-    public abstract void onSyncEnding(SyncContext context, boolean success);
-
-    /**
-     * Implement this to return true if the data in your content provider
-     * is read only.
-     */
-    public abstract boolean isReadOnly();
-
-    public abstract boolean getIsSyncable(Account account)
-            throws IOException, AuthenticatorException, OperationCanceledException;
-
-    /**
-     * Get diffs from the server since the last completed sync and put them
-     * into a temporary provider.
-     *
-     * @param context allows you to publish status and interact with the
-     *                user during interactive syncs.
-     * @param syncData used to track the progress this client has made in syncing data
-     *   from the server
-     * @param tempProvider this is where the diffs should be stored
-     * @param extras any extra data describing the sync that is desired
-     * @param syncInfo sync adapter-specific data that is used during a single sync operation
-     * @param syncResult information to track what happened during this sync attempt
-     */
-    public abstract void getServerDiffs(SyncContext context,
-            SyncData syncData, SyncableContentProvider tempProvider,
-            Bundle extras, Object syncInfo, SyncResult syncResult);
-
-    /**
-     * Send client diffs to the server, optionally receiving more diffs from the server
-     *
-     * @param context allows you to publish status and interact with the
-     *                user during interactive syncs.
-     * @param clientDiffs the diffs from the client
-     * @param serverDiffs the SyncableContentProvider that should be populated with
-*   the entries that were returned in response to an insert/update/delete request
-*   to the server
-     * @param syncResult information to track what happened during this sync attempt
-     * @param dontActuallySendDeletes
-     */
-    public abstract void sendClientDiffs(SyncContext context,
-            SyncableContentProvider clientDiffs,
-            SyncableContentProvider serverDiffs, SyncResult syncResult,
-            boolean dontActuallySendDeletes);
-
-    /**
-     * Reads the sync data from the ContentProvider
-     * @param contentProvider the ContentProvider to read from
-     * @return the SyncData for the provider. This may be null.
-     */
-    public SyncData readSyncData(SyncableContentProvider contentProvider) {
-        return null;
-    }
-
-    /**
-     * Create and return a new, empty SyncData object
-     */
-    public SyncData newSyncData() {
-        return null;
-    }
-
-    /**
-     * Stores the sync data in the Sync Stats database, keying it by
-     * the account that was set in the last call to onSyncStarting()
-     */
-    public void writeSyncData(SyncData syncData, SyncableContentProvider contentProvider) {}
-
-    /**
-     * Indicate to the SyncAdapter that the last sync that was started has
-     * been cancelled.
-     */
-    public abstract void onSyncCanceled();
-
-    /**
-     * Initializes the temporary content providers used during
-     * {@link TempProviderSyncAdapter#sendClientDiffs}.
-     * May copy relevant data from the underlying db into this provider so
-     * joins, etc., can work.
-     *
-     * @param cp The ContentProvider to initialize.
-     */
-    protected void initTempProvider(SyncableContentProvider cp) {}
-
-    protected Object createSyncInfo() {
-        return null;
-    }
-
-    /**
-     * Called when the accounts list possibly changed, to give the
-     * SyncAdapter a chance to do any necessary bookkeeping, e.g.
-     * to make sure that any required SubscribedFeeds subscriptions
-     * exist.
-     * @param accounts the list of accounts
-     */
-    public abstract void onAccountsChanged(Account[] accounts);
-
-    private Context mContext;
-
-    private class SyncThread extends Thread {
-        private final Account mAccount;
-        private final String mAuthority;
-        private final Bundle mExtras;
-        private final SyncContext mSyncContext;
-        private volatile boolean mIsCanceled = false;
-        private long mInitialTxBytes;
-        private long mInitialRxBytes;
-        private final SyncResult mResult;
-
-        SyncThread(SyncContext syncContext, Account account, String authority, Bundle extras) {
-            super("SyncThread");
-            mAccount = account;
-            mAuthority = authority;
-            mExtras = extras;
-            mSyncContext = syncContext;
-            mResult = new SyncResult();
-        }
-
-        void cancelSync() {
-            mIsCanceled = true;
-            if (mAdapterSyncStarted) onSyncCanceled();
-            if (mProviderSyncStarted) mProvider.onSyncCanceled();
-            // We may lose the last few sync events when canceling.  Oh well.
-            int uid = Process.myUid();
-            logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
-                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
-        }
-        
-        @Override
-        public void run() {
-            Process.setThreadPriority(Process.myTid(),
-                    Process.THREAD_PRIORITY_BACKGROUND);
-            int uid = Process.myUid();
-            mInitialTxBytes = TrafficStats.getUidTxBytes(uid);
-            mInitialRxBytes = TrafficStats.getUidRxBytes(uid);
-            try {
-                sync(mSyncContext, mAccount, mAuthority, mExtras);
-            } catch (SQLException e) {
-                Log.e(TAG, "Sync failed", e);
-                mResult.databaseError = true;
-            } finally {
-                mSyncThread = null;
-                if (!mIsCanceled) {
-                    logSyncDetails(TrafficStats.getUidTxBytes(uid) - mInitialTxBytes,
-                    TrafficStats.getUidRxBytes(uid) - mInitialRxBytes, mResult);
-                    mSyncContext.onFinished(mResult);
-                }
-            }
-        }
-
-        private void sync(SyncContext syncContext, Account account, String authority,
-                Bundle extras) {
-            mIsCanceled = false;
-
-            mProviderSyncStarted = false;
-            mAdapterSyncStarted = false;
-            String message = null;
-
-            // always attempt to initialize if the isSyncable state isn't set yet
-            int isSyncable = ContentResolver.getIsSyncable(account, authority);
-            if (isSyncable < 0) {
-                try {
-                    isSyncable = (getIsSyncable(account)) ? 1 : 0;
-                    ContentResolver.setIsSyncable(account, authority, isSyncable);
-                } catch (IOException e) {
-                    ++mResult.stats.numIoExceptions;
-                } catch (AuthenticatorException e) {
-                    ++mResult.stats.numParseExceptions;
-                } catch (OperationCanceledException e) {
-                    // do nothing
-                }
-            }
-
-            // if this is an initialization request then our work is done here
-            if (extras.getBoolean(ContentResolver.SYNC_EXTRAS_INITIALIZE, false)) {
-                return;
-            }
-
-            // if we aren't syncable then get out
-            if (isSyncable <= 0) {
-                return;
-            }
-
-            boolean manualSync = extras.getBoolean(ContentResolver.SYNC_EXTRAS_MANUAL, false);
-
-            try {
-                mProvider.onSyncStart(syncContext, account);
-                mProviderSyncStarted = true;
-                onSyncStarting(syncContext, account, manualSync, mResult);
-                if (mResult.hasError()) {
-                    message = "SyncAdapter failed while trying to start sync";
-                    return;
-                }
-                mAdapterSyncStarted = true;
-                if (mIsCanceled) {
-                    return;
-                }
-                final String syncTracingEnabledValue = SystemProperties.get(TAG + "Tracing");
-                final boolean syncTracingEnabled = !TextUtils.isEmpty(syncTracingEnabledValue);
-                try {
-                    if (syncTracingEnabled) {
-                        System.gc();
-                        System.gc();
-                        Debug.startMethodTracing("synctrace." + System.currentTimeMillis());
-                    }
-                    runSyncLoop(syncContext, account, extras);
-                } finally {
-                    if (syncTracingEnabled) Debug.stopMethodTracing();
-                }
-                onSyncEnding(syncContext, !mResult.hasError());
-                mAdapterSyncStarted = false;
-                mProvider.onSyncStop(syncContext, true);
-                mProviderSyncStarted = false;
-            } finally {
-                if (mAdapterSyncStarted) {
-                    mAdapterSyncStarted = false;
-                    onSyncEnding(syncContext, false);
-                }
-                if (mProviderSyncStarted) {
-                    mProviderSyncStarted = false;
-                    mProvider.onSyncStop(syncContext, false);
-                }
-                if (!mIsCanceled) {
-                    if (message != null) syncContext.setStatusText(message);
-                }
-            }
-        }
-
-        private void runSyncLoop(SyncContext syncContext, Account account, Bundle extras) {
-            TimingLogger syncTimer = new TimingLogger(TAG + "Profiling", "sync");
-            syncTimer.addSplit("start");
-            int loopCount = 0;
-            boolean tooManyGetServerDiffsAttempts = false;
-
-            final boolean overrideTooManyDeletions =
-                    extras.getBoolean(ContentResolver.SYNC_EXTRAS_OVERRIDE_TOO_MANY_DELETIONS,
-                            false);
-            final boolean discardLocalDeletions =
-                    extras.getBoolean(ContentResolver.SYNC_EXTRAS_DISCARD_LOCAL_DELETIONS, false);
-            boolean uploadOnly = extras.getBoolean(ContentResolver.SYNC_EXTRAS_UPLOAD,
-                    false /* default this flag to false */);
-            SyncableContentProvider serverDiffs = null;
-            TempProviderSyncResult result = new TempProviderSyncResult();
-            try {
-                if (!uploadOnly) {
-                    /**
-                     * This loop repeatedly calls SyncAdapter.getServerDiffs()
-                     * (to get changes from the feed) followed by
-                     * ContentProvider.merge() (to incorporate these changes
-                     * into the provider), stopping when the SyncData returned
-                     * from getServerDiffs() indicates that all the data was
-                     * fetched.
-                     */
-                    while (!mIsCanceled) {
-                        // Don't let a bad sync go forever
-                        if (loopCount++ == MAX_GET_SERVER_DIFFS_LOOP_COUNT) {
-                            Log.e(TAG, "runSyncLoop: Hit max loop count while getting server diffs "
-                                    + getClass().getName());
-                            // TODO: change the structure here to schedule a new sync
-                            // with a backoff time, keeping track to be sure
-                            // we don't keep doing this forever (due to some bug or
-                            // mismatch between the client and the server)
-                            tooManyGetServerDiffsAttempts = true;
-                            break;
-                        }
-
-                        // Get an empty content provider to put the diffs into
-                        if (serverDiffs != null) serverDiffs.close();
-                        serverDiffs = mProvider.getTemporaryInstance();
-
-                        // Get records from the server which will be put into the serverDiffs
-                        initTempProvider(serverDiffs);
-                        Object syncInfo = createSyncInfo();
-                        SyncData syncData = readSyncData(serverDiffs);
-                        // syncData will only be null if there was a demarshalling error
-                        // while reading the sync data.
-                        if (syncData == null) {
-                            mProvider.wipeAccount(account);
-                            syncData = newSyncData();
-                        }
-                        mResult.clear();
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: running getServerDiffs using syncData "
-                                    + syncData.toString());
-                        }
-                        getServerDiffs(syncContext, syncData, serverDiffs, extras, syncInfo,
-                                mResult);
-
-                        if (mIsCanceled) return;
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: result: " + mResult);
-                        }
-                        if (mResult.hasError()) return;
-                        if (mResult.partialSyncUnavailable) {
-                            if (Config.LOGD) {
-                                Log.d(TAG, "partialSyncUnavailable is set, setting "
-                                        + "ignoreSyncData and retrying");
-                            }
-                            mProvider.wipeAccount(account);
-                            continue;
-                        }
-
-                        // write the updated syncData back into the temp provider
-                        writeSyncData(syncData, serverDiffs);
-
-                        // apply the downloaded changes to the provider
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: running merge");
-                        }
-                        mProvider.merge(syncContext, serverDiffs,
-                                null /* don't return client diffs */, mResult);
-                        if (mIsCanceled) return;
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: result: " + mResult);
-                        }
-
-                        // if the server has no more changes then break out of the loop
-                        if (!mResult.moreRecordsToGet) {
-                            if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                                Log.v(TAG, "runSyncLoop: fetched all data, moving on");
-                            }
-                            break;
-                        }
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: more data to fetch, looping");
-                        }
-                    }
-                }
-
-                /**
-                 * This loop repeatedly calls ContentProvider.merge() followed
-                 * by SyncAdapter.merge() until either indicate that there is
-                 * no more work to do by returning null.
-                 * <p>
-                 * The initial ContentProvider.merge() returns a temporary
-                 * ContentProvider that contains any local changes that need
-                 * to be committed to the server.
-                 * <p>
-                 * The SyncAdapter.merge() calls upload the changes to the server
-                 * and populates temporary provider (the serverDiffs) with the
-                 * result.
-                 * <p>
-                 * Subsequent calls to ContentProvider.merge() incoporate the
-                 * result of previous SyncAdapter.merge() calls into the
-                 * real ContentProvider and again return a temporary
-                 * ContentProvider that contains any local changes that need
-                 * to be committed to the server.
-                 */
-                loopCount = 0;
-                boolean readOnly = isReadOnly();
-                long previousNumModifications = 0;
-                if (serverDiffs != null) {
-                    serverDiffs.close();
-                    serverDiffs = null;
-                }
-
-                // If we are discarding local deletions then we need to redownload all the items
-                // again (since some of them might have been deleted). We do this by deleting the
-                // sync data for the current account by writing in a null one.
-                if (discardLocalDeletions) {
-                    serverDiffs = mProvider.getTemporaryInstance();
-                    initTempProvider(serverDiffs);
-                    writeSyncData(null, serverDiffs);
-                }
-
-                while (!mIsCanceled) {
-                    if (Config.LOGV) {
-                        Log.v(TAG, "runSyncLoop: Merging diffs from server to client");
-                    }
-                    if (result.tempContentProvider != null) {
-                        result.tempContentProvider.close();
-                        result.tempContentProvider = null;
-                    }
-                    mResult.clear();
-                    mProvider.merge(syncContext, serverDiffs, readOnly ? null : result,
-                            mResult);
-                    if (mIsCanceled) return;
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "runSyncLoop: result: " + mResult);
-                    }
-
-                    SyncableContentProvider clientDiffs =
-                            readOnly ? null : result.tempContentProvider;
-                    if (clientDiffs == null) {
-                        // Nothing to commit back to the server
-                        if (Config.LOGV) Log.v(TAG, "runSyncLoop: No client diffs");
-                        break;
-                    }
-
-                    long numModifications = mResult.stats.numUpdates
-                            + mResult.stats.numDeletes
-                            + mResult.stats.numInserts;
-
-                    // as long as we are making progress keep resetting the loop count
-                    if (numModifications < previousNumModifications) {
-                        loopCount = 0;
-                    }
-                    previousNumModifications = numModifications;
-
-                    // Don't let a bad sync go forever
-                    if (loopCount++ >= MAX_UPLOAD_CHANGES_LOOP_COUNT) {
-                        Log.e(TAG, "runSyncLoop: Hit max loop count while syncing "
-                                + getClass().getName());
-                        mResult.tooManyRetries = true;
-                        break;
-                    }
-
-                    if (!overrideTooManyDeletions && !discardLocalDeletions
-                            && hasTooManyDeletions(mResult.stats)) {
-                        if (Config.LOGD) {
-                            Log.d(TAG, "runSyncLoop: Too many deletions were found in provider "
-                                    + getClass().getName() + ", not doing any more updates");
-                        }
-                        long numDeletes = mResult.stats.numDeletes;
-                        mResult.stats.clear();
-                        mResult.tooManyDeletions = true;
-                        mResult.stats.numDeletes = numDeletes;
-                        break;
-                    }
-
-                    if (Config.LOGV) Log.v(TAG, "runSyncLoop: Merging diffs from client to server");
-                    if (serverDiffs != null) serverDiffs.close();
-                    serverDiffs = clientDiffs.getTemporaryInstance();
-                    initTempProvider(serverDiffs);
-                    mResult.clear();
-                    sendClientDiffs(syncContext, clientDiffs, serverDiffs, mResult,
-                            discardLocalDeletions);
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "runSyncLoop: result: " + mResult);
-                    }
-
-                    if (!mResult.madeSomeProgress()) {
-                        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                            Log.v(TAG, "runSyncLoop: No data from client diffs merge");
-                        }
-                        break;
-                    }
-                    if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                        Log.v(TAG, "runSyncLoop: made some progress, looping");
-                    }
-                }
-
-                // add in any status codes that we saved from earlier
-                mResult.tooManyRetries |= tooManyGetServerDiffsAttempts;
-                if (Log.isLoggable(TAG, Log.VERBOSE)) {
-                    Log.v(TAG, "runSyncLoop: final result: " + mResult);
-                }
-            } finally {
-                // do this in the finally block to guarantee that is is set and not overwritten
-                if (discardLocalDeletions) {
-                    mResult.fullSyncRequested = true;
-                }
-                if (serverDiffs != null) serverDiffs.close();
-                if (result.tempContentProvider != null) result.tempContentProvider.close();
-                syncTimer.addSplit("stop");
-                syncTimer.dumpToLog();
-            }
-        }
-    }
-
-    /**
-     * Logs details on the sync.
-     * Normally this will be overridden by a subclass that will provide
-     * provider-specific details.
-     * 
-     * @param bytesSent number of bytes the sync sent over the network
-     * @param bytesReceived number of bytes the sync received over the network
-     * @param result The SyncResult object holding info on the sync
-     */
-    protected void logSyncDetails(long bytesSent, long bytesReceived, SyncResult result) {
-        EventLog.writeEvent(SyncAdapter.LOG_SYNC_DETAILS, TAG, bytesSent, bytesReceived, "");
-    }
-
-    public void startSync(SyncContext syncContext, Account account, String authority,
-            Bundle extras) {
-        if (mSyncThread != null) {
-            syncContext.onFinished(SyncResult.ALREADY_IN_PROGRESS);
-            return;
-        }
-
-        mSyncThread = new SyncThread(syncContext, account, authority, extras);
-        mSyncThread.start();
-    }
-
-    public void cancelSync() {
-        if (mSyncThread != null) {
-            mSyncThread.cancelSync();
-        }
-    }
-
-    protected boolean hasTooManyDeletions(SyncStats stats) {
-        long numEntries = stats.numEntries;
-        long numDeletedEntries = stats.numDeletes;
-
-        long percentDeleted = (numDeletedEntries == 0)
-                ? 0
-                : (100 * numDeletedEntries /
-                        (numEntries + numDeletedEntries));
-        boolean tooManyDeletions =
-                (numDeletedEntries > NUM_ALLOWED_SIMULTANEOUS_DELETIONS)
-                && (percentDeleted > PERCENT_ALLOWED_SIMULTANEOUS_DELETIONS);
-        return tooManyDeletions;
-    }
-}
diff --git a/core/java/android/content/TempProviderSyncResult.java b/core/java/android/content/TempProviderSyncResult.java
deleted file mode 100644
index 81f6f79..0000000
--- a/core/java/android/content/TempProviderSyncResult.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Copyright (C) 2007 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 android.content;
-
-/**
- * Used to hold data returned from a given phase of a TempProviderSync.
- * @hide
- */
-public class TempProviderSyncResult {
-    /**
-     * An interface to a temporary content provider that contains
-     * the result of updates that were sent to the server. This
-     * provider must be merged into the permanent content provider.
-     * This may be null, which indicates that there is nothing to
-     * merge back into the content provider.
-     */
-    public SyncableContentProvider tempContentProvider;
-
-    public TempProviderSyncResult() {
-        tempContentProvider = null;
-    }
-}
diff --git a/core/java/android/provider/ContactsContract.java b/core/java/android/provider/ContactsContract.java
index 117de15..b5c9900 100644
--- a/core/java/android/provider/ContactsContract.java
+++ b/core/java/android/provider/ContactsContract.java
@@ -30,6 +30,7 @@
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteException;
 import android.graphics.Rect;
 import android.net.Uri;
 import android.os.RemoteException;
@@ -1447,7 +1448,11 @@
                         if (cursor.isNull(columnIndex)) {
                             // don't put anything
                         } else {
-                            cv.put(key, cursor.getString(columnIndex));
+                            try {
+                                cv.put(key, cursor.getString(columnIndex));
+                            } catch (SQLiteException e) {
+                                cv.put(key, cursor.getBlob(columnIndex));
+                            }
                         }
                         // TODO: go back to this version of the code when bug
                         // http://b/issue?id=2306370 is fixed.
diff --git a/preloaded-classes b/preloaded-classes
index a50ccc8..762bac6 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -126,9 +126,6 @@
 android.bluetooth.IBluetoothHeadset$Stub$Proxy
 android.bluetooth.IBluetoothPbap$Stub
 android.bluetooth.ScoSocket
-android.content.AbstractSyncableContentProvider
-android.content.AbstractSyncableContentProvider$DatabaseHelper
-android.content.AbstractTableMerger
 android.content.AsyncQueryHandler
 android.content.BroadcastReceiver
 android.content.ComponentName
@@ -161,15 +158,9 @@
 android.content.IntentSender$1
 android.content.SearchRecentSuggestionsProvider
 android.content.SearchRecentSuggestionsProvider$DatabaseHelper
-android.content.SyncAdapter
-android.content.SyncAdapter$Transport
 android.content.SyncAdapterType
 android.content.SyncResult
-android.content.SyncStateContentProviderHelper
 android.content.SyncStats
-android.content.SyncableContentProvider
-android.content.TempProviderSyncAdapter
-android.content.TempProviderSyncAdapter$SyncThread
 android.content.UriMatcher
 android.content.pm.ActivityInfo
 android.content.pm.ApplicationInfo
diff --git a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java b/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
deleted file mode 100644
index a8af7f8..0000000
--- a/tests/FrameworkTest/tests/src/android/content/AbstractTableMergerTest.java
+++ /dev/null
@@ -1,587 +0,0 @@
-package android.content;
-
-import com.google.android.collect.Lists;
-import com.google.android.collect.Sets;
-
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.test.AndroidTestCase;
-import android.text.TextUtils;
-import android.accounts.Account;
-
-import java.util.ArrayList;
-import java.util.Map;
-import java.util.SortedSet;
-
-/** Unit test for {@link android.content.AbstractTableMerger}. */
-public class AbstractTableMergerTest extends AndroidTestCase {
-    MockSyncableContentProvider mRealProvider;
-    MockSyncableContentProvider mTempProvider;
-    MockTableMerger mMerger;
-    MockSyncContext mSyncContext;
-
-    static final String TABLE_NAME = "items";
-    static final String DELETED_TABLE_NAME = "deleted_items";
-    static final Uri CONTENT_URI = Uri.parse("content://testdata");
-    static final Uri TABLE_URI = Uri.withAppendedPath(CONTENT_URI, TABLE_NAME);
-    static final Uri DELETED_TABLE_URI = Uri.withAppendedPath(CONTENT_URI, DELETED_TABLE_NAME);
-
-    private final Account ACCOUNT = new Account("account@goo.com", "example.type");
-
-    private final ArrayList<Expectation> mExpectations = Lists.newArrayList();
-
-    static class Expectation {
-        enum Type {
-            UPDATE,
-            INSERT,
-            DELETE,
-            RESOLVE
-        }
-
-        Type mType;
-        ContentValues mValues;
-        Long mLocalRowId;
-
-        Expectation(Type type, Long localRowId, ContentValues values) {
-            mType = type;
-            mValues = values;
-            mLocalRowId = localRowId;
-            if (type == Type.DELETE) {
-                assertNull(values);
-            } else {
-                assertFalse(values.containsKey("_id"));
-            }
-        }
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        mSyncContext = new MockSyncContext();
-        mRealProvider = new MockSyncableContentProvider();
-        mTempProvider = mRealProvider.getTemporaryInstance();
-        mMerger = new MockTableMerger(mRealProvider.getDatabase(),
-                TABLE_NAME, TABLE_URI, DELETED_TABLE_NAME, DELETED_TABLE_URI);
-        mExpectations.clear();
-    }
-
-    ContentValues newValues(String data, String syncId, Account syncAccount,
-            String syncTime, String syncVersion, Long syncLocalId) {
-        ContentValues values = new ContentValues();
-        if (data != null) values.put("data", data);
-        if (syncTime != null) values.put("_sync_time", syncTime);
-        if (syncVersion != null) values.put("_sync_version", syncVersion);
-        if (syncId != null) values.put("_sync_id", syncId);
-        if (syncAccount != null) {
-            values.put("_sync_account", syncAccount.name);
-            values.put("_sync_account_type", syncAccount.type);
-        }
-        values.put("_sync_local_id", syncLocalId);
-        values.put("_sync_dirty", 0);
-        return values;
-    }
-
-    ContentValues newDeletedValues(String syncId, Account syncAccount, String syncVersion,
-            Long syncLocalId) {
-        ContentValues values = new ContentValues();
-        if (syncVersion != null) values.put("_sync_version", syncVersion);
-        if (syncId != null) values.put("_sync_id", syncId);
-        if (syncAccount != null) {
-            values.put("_sync_account", syncAccount.name);
-            values.put("_sync_account_type", syncAccount.type);
-        }
-        if (syncLocalId != null) values.put("_sync_local_id", syncLocalId);
-        return values;
-    }
-
-    ContentValues newModifyData(String data) {
-        ContentValues values = new ContentValues();
-        values.put("data", data);
-        values.put("_sync_dirty", 1);
-        return values;
-    }
-
-    // Want to test adding, changing, deleting entries to a provider that has extra entries
-    // before and after the entries being changed.
-    public void testInsert() {
-        // add rows to the real provider
-        // add new row to the temp provider
-        final ContentValues row1 = newValues("d1", "si1", ACCOUNT, "st1", "sv1", null);
-        mTempProvider.insert(TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.INSERT, null /* syncLocalId */, row1));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testUpdateWithLocalId() {
-        // add rows to the real provider
-        // add new row to the temp provider that matches an unsynced row in the real provider
-        final ContentValues row1 = newValues("d1", "si1", ACCOUNT, "st1", "sv1", 11L);
-        mTempProvider.insert(TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.UPDATE, 11L, row1));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testUpdateWithoutLocalId() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-
-        // add new row to the temp provider that matches an unsynced row in the real provider
-        final ContentValues row1 = newValues("d2", "si1", ACCOUNT, "st2", "sv2", null);
-        mTempProvider.insert(TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.UPDATE, ContentUris.parseId(i1), row1));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testResolve() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-        mRealProvider.update(TABLE_URI, newModifyData("d2"), null, null);
-
-        // add row to the temp provider that matches a dirty, synced row in the real provider
-        final ContentValues row1 = newValues("d3", "si1", ACCOUNT, "st2", "sv2", null);
-        mTempProvider.insert(TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.RESOLVE, ContentUris.parseId(i1), row1));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testResolveWithLocalId() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-        mRealProvider.update(TABLE_URI, newModifyData("d2"), null, null);
-
-        // add row to the temp provider that matches a dirty, synced row in the real provider
-        ContentValues row1 = newValues("d2", "si1", ACCOUNT, "st2", "sv2", ContentUris.parseId(i1));
-        mTempProvider.insert(TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.UPDATE, ContentUris.parseId(i1), row1));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testDeleteRowAfterDelete() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-
-        // add a deleted record to the temp provider
-        ContentValues row1 = newDeletedValues(null, null, null, ContentUris.parseId(i1));
-        mTempProvider.insert(DELETED_TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testDeleteRowAfterInsert() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI, newModifyData("d1"));
-
-        // add a deleted record to the temp provider
-        ContentValues row1 = newDeletedValues(null, null, null, ContentUris.parseId(i1));
-        mTempProvider.insert(DELETED_TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testDeleteRowAfterUpdate() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-
-        // add a deleted record to the temp provider
-        ContentValues row1 = newDeletedValues("si1", ACCOUNT, "sv1", ContentUris.parseId(i1));
-        mTempProvider.insert(DELETED_TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    public void testDeleteRowFromServer() {
-        // add rows to the real provider
-        Uri i1 = mRealProvider.insert(TABLE_URI,
-                newValues("d1", "si1", ACCOUNT, "st1", "sv1", null));
-
-        // add a deleted record to the temp provider
-        ContentValues row1 = newDeletedValues("si1", ACCOUNT, "sv1", null);
-        mTempProvider.insert(DELETED_TABLE_URI, row1);
-
-        // add expected callbacks to merger
-        mExpectations.add(new Expectation(Expectation.Type.DELETE, ContentUris.parseId(i1), null));
-
-        // run merger
-        SyncResult syncResult = new SyncResult();
-        mMerger.mergeServerDiffs(mSyncContext, ACCOUNT, mTempProvider, syncResult);
-
-        // check that all expectations were met
-        assertEquals("not all expectations were met", 0, mExpectations.size());
-    }
-
-    class MockTableMerger extends AbstractTableMerger {
-        public MockTableMerger(SQLiteDatabase database, String table, Uri tableURL,
-                String deletedTable, Uri deletedTableURL) {
-            super(database, table, tableURL, deletedTable, deletedTableURL);
-        }
-
-        public void insertRow(ContentProvider diffs, Cursor diffsCursor) {
-            Expectation expectation = mExpectations.remove(0);
-            checkExpectation(expectation,
-                    Expectation.Type.INSERT, null /* syncLocalId */, diffsCursor);
-        }
-
-        public void updateRow(long localPersonID, ContentProvider diffs, Cursor diffsCursor) {
-            Expectation expectation = mExpectations.remove(0);
-            checkExpectation(expectation, Expectation.Type.UPDATE, localPersonID, diffsCursor);
-        }
-
-        public void resolveRow(long localPersonID, String syncID, ContentProvider diffs,
-                Cursor diffsCursor) {
-            Expectation expectation = mExpectations.remove(0);
-            checkExpectation(expectation, Expectation.Type.RESOLVE, localPersonID, diffsCursor);
-        }
-
-        @Override
-        public void deleteRow(Cursor cursor) {
-            Expectation expectation = mExpectations.remove(0);
-            assertEquals(expectation.mType, Expectation.Type.DELETE);
-            assertNotNull(expectation.mLocalRowId);
-            final long localRowId = cursor.getLong(cursor.getColumnIndexOrThrow("_id"));
-            assertEquals((long)expectation.mLocalRowId, localRowId);
-            cursor.moveToNext();
-            mDb.delete(TABLE_NAME, "_id=" + localRowId, null);
-        }
-
-        protected void notifyChanges() {
-            throw new UnsupportedOperationException();
-        }
-
-        void checkExpectation(Expectation expectation,
-                Expectation.Type actualType, Long localRowId,
-                Cursor cursor) {
-            assertEquals(expectation.mType, actualType);
-            assertEquals(expectation.mLocalRowId, localRowId);
-
-            final SortedSet<String> actualKeys = Sets.newSortedSet(cursor.getColumnNames());
-            final SortedSet<String> expectedKeys = Sets.newSortedSet();
-            for (Map.Entry<String, Object> entry : expectation.mValues.valueSet()) {
-                expectedKeys.add(entry.getKey());
-            }
-            actualKeys.remove("_id");
-            actualKeys.remove("_sync_mark");
-            actualKeys.remove("_sync_local_id");
-            expectedKeys.remove("_sync_local_id");
-            expectedKeys.remove("_id");
-            assertEquals("column mismatch",
-                    TextUtils.join(",", expectedKeys), TextUtils.join(",", actualKeys));
-
-//            if (localRowId != null) {
-//                assertEquals((long) localRowId,
-//                        cursor.getLong(cursor.getColumnIndexOrThrow("_sync_local_id")));
-//            } else {
-//                assertTrue("unexpected _sync_local_id, "
-//                        + cursor.getLong(cursor.getColumnIndexOrThrow("_sync_local_id")),
-//                        cursor.isNull(cursor.getColumnIndexOrThrow("_sync_local_id")));
-//            }
-
-            for (String name : cursor.getColumnNames()) {
-                if ("_id".equals(name)) {
-                    continue;
-                }
-                if (cursor.isNull(cursor.getColumnIndexOrThrow(name))) {
-                    assertNull(expectation.mValues.getAsString(name));
-                } else {
-                    String actualValue =
-                            cursor.getString(cursor.getColumnIndexOrThrow(name));
-                    assertEquals("mismatch on column " + name,
-                            expectation.mValues.getAsString(name), actualValue);
-                }
-            }
-        }
-    }
-
-    class MockSyncableContentProvider extends SyncableContentProvider {
-        SQLiteDatabase mDb;
-        boolean mIsTemporary;
-        boolean mContainsDiffs;
-
-        private final UriMatcher sURIMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
-        private static final int MATCHER_ITEMS = 0;
-        private static final int MATCHER_DELETED_ITEMS = 1;
-
-        public MockSyncableContentProvider() {
-            mIsTemporary = false;
-            setContainsDiffs(false);
-            sURIMatcher.addURI(CONTENT_URI.getAuthority(), "items", MATCHER_ITEMS);
-            sURIMatcher.addURI(CONTENT_URI.getAuthority(), "deleted_items", MATCHER_DELETED_ITEMS);
-
-            mDb = SQLiteDatabase.create(null);
-            mDb.execSQL("CREATE TABLE items ("
-                    + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
-                    + "data TEXT, "
-                    + "_sync_time TEXT, "
-                    + "_sync_version TEXT, "
-                    + "_sync_id TEXT, "
-                    + "_sync_local_id INTEGER, "
-                    + "_sync_dirty INTEGER NOT NULL DEFAULT 0, "
-                    + "_sync_account TEXT, "
-                    + "_sync_account_type TEXT, "
-                    + "_sync_mark INTEGER)");
-
-            mDb.execSQL("CREATE TABLE deleted_items ("
-                    + "_id INTEGER PRIMARY KEY AUTOINCREMENT, "
-                    + "_sync_version TEXT, "
-                    + "_sync_id TEXT, "
-                    + "_sync_local_id INTEGER, "
-                    + "_sync_account TEXT, "
-                    + "_sync_account_type TEXT, "
-                    + "_sync_mark INTEGER)");
-        }
-
-        public boolean onCreate() {
-            throw new UnsupportedOperationException();
-        }
-
-        public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
-                String sortOrder) {
-            int match = sURIMatcher.match(uri);
-            switch (match) {
-                case MATCHER_ITEMS:
-                    return mDb.query(TABLE_NAME, projection, selection, selectionArgs,
-                            null, null, sortOrder);
-                case MATCHER_DELETED_ITEMS:
-                    return mDb.query(DELETED_TABLE_NAME, projection, selection, selectionArgs,
-                            null, null, sortOrder);
-                default:
-                    throw new UnsupportedOperationException("Cannot query URL: " + uri);
-            }
-        }
-
-        public String getType(Uri uri) {
-            throw new UnsupportedOperationException();
-        }
-
-        public Uri insert(Uri uri, ContentValues values) {
-            int match = sURIMatcher.match(uri);
-            switch (match) {
-                case MATCHER_ITEMS: {
-                    long id = mDb.insert(TABLE_NAME, "_id", values);
-                    return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
-                }
-                case MATCHER_DELETED_ITEMS: {
-                    long id = mDb.insert(DELETED_TABLE_NAME, "_id", values);
-                    return CONTENT_URI.buildUpon().appendPath(String.valueOf(id)).build();
-                }
-                default:
-                    throw new UnsupportedOperationException("Cannot query URL: " + uri);
-            }
-        }
-
-        public int delete(Uri uri, String selection, String[] selectionArgs) {
-            int match = sURIMatcher.match(uri);
-            switch (match) {
-                case MATCHER_ITEMS:
-                    return mDb.delete(TABLE_NAME, selection, selectionArgs);
-                case MATCHER_DELETED_ITEMS:
-                    return mDb.delete(DELETED_TABLE_NAME, selection, selectionArgs);
-                default:
-                    throw new UnsupportedOperationException("Cannot query URL: " + uri);
-            }
-        }
-
-        public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-            int match = sURIMatcher.match(uri);
-            switch (match) {
-                case MATCHER_ITEMS:
-                    return mDb.update(TABLE_NAME, values, selection, selectionArgs);
-                case MATCHER_DELETED_ITEMS:
-                    return mDb.update(DELETED_TABLE_NAME, values, selection, selectionArgs);
-                default:
-                    throw new UnsupportedOperationException("Cannot query URL: " + uri);
-            }
-        }
-
-        protected boolean isTemporary() {
-            return mIsTemporary;
-        }
-
-        public void close() {
-            throw new UnsupportedOperationException();
-        }
-
-        protected void bootstrapDatabase(SQLiteDatabase db) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected boolean upgradeDatabase(SQLiteDatabase db, int oldVersion, int newVersion) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected void onDatabaseOpened(SQLiteDatabase db) {
-            throw new UnsupportedOperationException();
-        }
-
-        public MockSyncableContentProvider getTemporaryInstance() {
-            MockSyncableContentProvider temp = new MockSyncableContentProvider();
-            temp.mIsTemporary = true;
-            temp.setContainsDiffs(true);
-            return temp;
-        }
-
-        public SQLiteDatabase getDatabase() {
-            return mDb;
-        }
-
-        public boolean getContainsDiffs() {
-            return mContainsDiffs;
-        }
-
-        public void setContainsDiffs(boolean containsDiffs) {
-            mContainsDiffs = containsDiffs;
-        }
-
-        protected Iterable<? extends AbstractTableMerger> getMergers() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean changeRequiresLocalSync(Uri uri) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void onSyncStart(SyncContext context, Account account) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void onSyncStop(SyncContext context, boolean success) {
-            throw new UnsupportedOperationException();
-        }
-
-        public Account getSyncingAccount() {
-            throw new UnsupportedOperationException();
-        }
-
-        public void merge(SyncContext context, SyncableContentProvider diffs,
-                TempProviderSyncResult result, SyncResult syncResult) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void onSyncCanceled() {
-            throw new UnsupportedOperationException();
-        }
-
-        public boolean isMergeCancelled() {
-            return false;
-        }
-
-        protected int updateInternal(Uri url, ContentValues values, String selection,
-                String[] selectionArgs) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected int deleteInternal(Uri url, String selection, String[] selectionArgs) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected Uri insertInternal(Uri url, ContentValues values) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected Cursor queryInternal(Uri url, String[] projection, String selection,
-                String[] selectionArgs, String sortOrder) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected void onAccountsChanged(Account[] accountsArray) {
-            throw new UnsupportedOperationException();
-        }
-
-        protected void deleteRowsForRemovedAccounts(Map<Account, Boolean> accounts, String table
-        ) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void wipeAccount(Account account) {
-            throw new UnsupportedOperationException();
-        }
-
-        public byte[] readSyncDataBytes(Account account) {
-            throw new UnsupportedOperationException();
-        }
-
-        public void writeSyncDataBytes(Account account, byte[] data) {
-            throw new UnsupportedOperationException();
-        }
-    }
-
-    class MockSyncContext extends SyncContext {
-        public MockSyncContext() {
-            super(null);
-        }
-
-        @Override
-        public void setStatusText(String message) {
-        }
-    }
-}
