diff --git a/Android.mk b/Android.mk
index 42a6b31..ca76fb4 100644
--- a/Android.mk
+++ b/Android.mk
@@ -85,8 +85,10 @@
 	core/java/android/bluetooth/IBluetoothDevice.aidl \
 	core/java/android/bluetooth/IBluetoothDeviceCallback.aidl \
 	core/java/android/bluetooth/IBluetoothHeadset.aidl \
+    core/java/android/content/IContentService.aidl \
 	core/java/android/content/ISyncAdapter.aidl \
 	core/java/android/content/ISyncContext.aidl \
+    core/java/android/content/ISyncStatusObserver.aidl \
 	core/java/android/content/pm/IPackageDataObserver.aidl \
 	core/java/android/content/pm/IPackageDeleteObserver.aidl \
 	core/java/android/content/pm/IPackageInstallObserver.aidl \
diff --git a/api/current.xml b/api/current.xml
index f01ed14..2bab739 100644
--- a/api/current.xml
+++ b/api/current.xml
@@ -92268,6 +92268,19 @@
  visibility="public"
 >
 </method>
+<method name="getBroadcastCookie"
+ return="java.lang.Object"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="index" type="int">
+</parameter>
+</method>
 <method name="getBroadcastItem"
  return="E"
  abstract="false"
@@ -92305,6 +92318,21 @@
 <parameter name="callback" type="E">
 </parameter>
 </method>
+<method name="onCallbackDied"
+ return="void"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="E">
+</parameter>
+<parameter name="cookie" type="java.lang.Object">
+</parameter>
+</method>
 <method name="register"
  return="boolean"
  abstract="false"
@@ -92318,6 +92346,21 @@
 <parameter name="callback" type="E">
 </parameter>
 </method>
+<method name="register"
+ return="boolean"
+ abstract="false"
+ native="false"
+ synchronized="false"
+ static="false"
+ final="false"
+ deprecated="not deprecated"
+ visibility="public"
+>
+<parameter name="callback" type="E">
+</parameter>
+<parameter name="cookie" type="java.lang.Object">
+</parameter>
+</method>
 <method name="unregister"
  return="boolean"
  abstract="false"
diff --git a/core/java/android/content/ActiveSyncInfo.aidl b/core/java/android/content/ActiveSyncInfo.aidl
new file mode 100644
index 0000000..1142206
--- /dev/null
+++ b/core/java/android/content/ActiveSyncInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+parcelable ActiveSyncInfo;
diff --git a/core/java/android/content/ActiveSyncInfo.java b/core/java/android/content/ActiveSyncInfo.java
new file mode 100644
index 0000000..63be8d1
--- /dev/null
+++ b/core/java/android/content/ActiveSyncInfo.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.os.Parcel;
+import android.os.Parcelable.Creator;
+
+/** @hide */
+public class ActiveSyncInfo {
+    public final int authorityId;
+    public final String account;
+    public final String authority;
+    public final long startTime;
+    
+    ActiveSyncInfo(int authorityId, String account, String authority,
+            long startTime) {
+        this.authorityId = authorityId;
+        this.account = account;
+        this.authority = authority;
+        this.startTime = startTime;
+    }
+    
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(authorityId);
+        parcel.writeString(account);
+        parcel.writeString(authority);
+        parcel.writeLong(startTime);
+    }
+
+    ActiveSyncInfo(Parcel parcel) {
+        authorityId = parcel.readInt();
+        account = parcel.readString();
+        authority = parcel.readString();
+        startTime = parcel.readLong();
+    }
+    
+    public static final Creator<ActiveSyncInfo> CREATOR = new Creator<ActiveSyncInfo>() {
+        public ActiveSyncInfo createFromParcel(Parcel in) {
+            return new ActiveSyncInfo(in);
+        }
+
+        public ActiveSyncInfo[] newArray(int size) {
+            return new ActiveSyncInfo[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/core/java/android/content/ContentResolver.java b/core/java/android/content/ContentResolver.java
index 0a71d57..74144fc 100644
--- a/core/java/android/content/ContentResolver.java
+++ b/core/java/android/content/ContentResolver.java
@@ -25,9 +25,13 @@
 import android.database.IContentObserver;
 import android.net.Uri;
 import android.os.Bundle;
+import android.os.IBinder;
 import android.os.ParcelFileDescriptor;
 import android.os.RemoteException;
+import android.os.ServiceManager;
 import android.text.TextUtils;
+import android.util.Config;
+import android.util.Log;
 
 import java.io.File;
 import java.io.FileInputStream;
@@ -85,8 +89,7 @@
      */
     public static final String CURSOR_DIR_BASE_TYPE = "vnd.android.cursor.dir";
     
-    public ContentResolver(Context context)
-    {
+    public ContentResolver(Context context) {
         mContext = context;
     }
 
@@ -605,7 +608,7 @@
             ContentObserver observer)
     {
         try {
-            ContentServiceNative.getDefault().registerContentObserver(uri, notifyForDescendents,
+            getContentService().registerContentObserver(uri, notifyForDescendents,
                     observer.getContentObserver());
         } catch (RemoteException e) {
         }
@@ -621,7 +624,7 @@
         try {
             IContentObserver contentObserver = observer.releaseContentObserver();
             if (contentObserver != null) {
-                ContentServiceNative.getDefault().unregisterContentObserver(
+                getContentService().unregisterContentObserver(
                         contentObserver);
             }
         } catch (RemoteException e) {
@@ -651,7 +654,7 @@
      */
     public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
         try {
-            ContentServiceNative.getDefault().notifyChange(
+            getContentService().notifyChange(
                     uri, observer == null ? null : observer.getContentObserver(),
                     observer != null && observer.deliverSelfNotifications(), syncToNetwork);
         } catch (RemoteException e) {
@@ -677,7 +680,7 @@
     public void startSync(Uri uri, Bundle extras) {
         validateSyncExtrasBundle(extras);
         try {
-            ContentServiceNative.getDefault().startSync(uri, extras);
+            getContentService().startSync(uri, extras);
         } catch (RemoteException e) {
         }
     }
@@ -718,7 +721,7 @@
 
     public void cancelSync(Uri uri) {
         try {
-            ContentServiceNative.getDefault().cancelSync(uri);
+            getContentService().cancelSync(uri);
         } catch (RemoteException e) {
         }
     }
@@ -779,6 +782,22 @@
         }
     }
 
+    /** @hide */
+    public static final String CONTENT_SERVICE_NAME = "content";
+    
+    /** @hide */
+    public static IContentService getContentService() {
+        if (sContentService != null) {
+            return sContentService;
+        }
+        IBinder b = ServiceManager.getService(CONTENT_SERVICE_NAME);
+        if (Config.LOGV) Log.v("ContentService", "default service binder = " + b);
+        sContentService = IContentService.Stub.asInterface(b);
+        if (Config.LOGV) Log.v("ContentService", "default service = " + sContentService);
+        return sContentService;
+    }
+    
+    private static IContentService sContentService;
     private final Context mContext;
     private static final String TAG = "ContentResolver";
 }
diff --git a/core/java/android/content/ContentService.java b/core/java/android/content/ContentService.java
index b028868..6cd2c54 100644
--- a/core/java/android/content/ContentService.java
+++ b/core/java/android/content/ContentService.java
@@ -21,6 +21,7 @@
 import android.net.Uri;
 import android.os.Bundle;
 import android.os.IBinder;
+import android.os.Parcel;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.util.Config;
@@ -34,7 +35,7 @@
 /**
  * {@hide}
  */
-public final class ContentService extends ContentServiceNative {
+public final class ContentService extends IContentService.Stub {
     private static final String TAG = "ContentService";
     private Context mContext;
     private boolean mFactoryTest;
@@ -73,6 +74,21 @@
         }
     }
 
+    @Override
+    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
+            throws RemoteException {
+        try {
+            return super.onTransact(code, data, reply, flags);
+        } catch (RuntimeException e) {
+            // The content service only throws security exceptions, so let's
+            // log all others.
+            if (!(e instanceof SecurityException)) {
+                Log.e(TAG, "Content Service Crash", e);
+            }
+            throw e;
+        }
+    }
+
     /*package*/ ContentService(Context context, boolean factoryTest) {
         mContext = context;
         mFactoryTest = factoryTest;
@@ -204,9 +220,158 @@
         }
     }
 
+    public boolean getSyncProviderAutomatically(String providerName) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
+                "no permission to read the sync settings");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().getSyncProviderAutomatically(
+                        null, providerName);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+
+    public void setSyncProviderAutomatically(String providerName, boolean sync) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                "no permission to write the sync settings");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().setSyncProviderAutomatically(
+                        null, providerName, sync);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public boolean getListenForNetworkTickles() {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
+                "no permission to read the sync settings");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().getListenForNetworkTickles();
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+    
+    public void setListenForNetworkTickles(boolean flag) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
+                "no permission to write the sync settings");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().setListenForNetworkTickles(flag);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+
+    public boolean isSyncActive(String account, String authority) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
+                "no permission to read the sync stats");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().isSyncActive(
+                        account, authority);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+    
+    public ActiveSyncInfo getActiveSync() {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
+                "no permission to read the sync stats");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().getActiveSync();
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return null;
+    }
+    
+    public SyncStatusInfo getStatusByAuthority(String authority) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
+                "no permission to read the sync stats");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().getStatusByAuthority(
+                        authority);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return null;
+    }
+    
+    public boolean isAuthorityPending(String account, String authority) {
+        mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
+                "no permission to read the sync stats");
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                return syncManager.getSyncStorageEngine().isAuthorityPending(
+                        account, authority);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+        return false;
+    }
+    
+    public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().addStatusChangeListener(
+                        mask, callback);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+    
+    public void removeStatusChangeListener(ISyncStatusObserver callback) {
+        long identityToken = clearCallingIdentity();
+        try {
+            SyncManager syncManager = getSyncManager();
+            if (syncManager != null) {
+                syncManager.getSyncStorageEngine().removeStatusChangeListener(
+                        callback);
+            }
+        } finally {
+            restoreCallingIdentity(identityToken);
+        }
+    }
+    
     public static IContentService main(Context context, boolean factoryTest) {
         ContentService service = new ContentService(context, factoryTest);
-        ServiceManager.addService("content", service);
+        ServiceManager.addService(ContentResolver.CONTENT_SERVICE_NAME, service);
         return service;
     }
 
diff --git a/core/java/android/content/ContentServiceNative.java b/core/java/android/content/ContentServiceNative.java
deleted file mode 100644
index 364f9ee..0000000
--- a/core/java/android/content/ContentServiceNative.java
+++ /dev/null
@@ -1,216 +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.IContentObserver;
-import android.net.Uri;
-import android.os.Binder;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.Parcel;
-import android.os.ServiceManager;
-import android.os.Bundle;
-import android.util.Config;
-import android.util.Log;
-
-/**
- * {@hide}
- */
-abstract class ContentServiceNative extends Binder implements IContentService
-{
-    public ContentServiceNative()
-    {
-        attachInterface(this, descriptor);
-    }
-
-    /**
-     * Cast a Binder object into a content resolver interface, generating
-     * a proxy if needed.
-     */
-    static public IContentService asInterface(IBinder obj)
-    {
-        if (obj == null) {
-            return null;
-        }
-        IContentService in =
-            (IContentService)obj.queryLocalInterface(descriptor);
-        if (in != null) {
-            return in;
-        }
-
-        return new ContentServiceProxy(obj);
-    }
-
-    /**
-     * Retrieve the system's default/global content service.
-     */
-    static public IContentService getDefault()
-    {
-        if (gDefault != null) {
-            return gDefault;
-        }
-        IBinder b = ServiceManager.getService("content");
-        if (Config.LOGV) Log.v("ContentService", "default service binder = " + b);
-        gDefault = asInterface(b);
-        if (Config.LOGV) Log.v("ContentService", "default service = " + gDefault);
-        return gDefault;
-    }
-
-    @Override
-    public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
-    {
-        try {
-        switch (code) {
-            case 5038: {
-                data.readString(); // ignore the interface token that service generated
-                Uri uri = Uri.parse(data.readString());
-                notifyChange(uri, null, false, false);
-                return true;
-            }
-            
-            case REGISTER_CONTENT_OBSERVER_TRANSACTION: {
-                Uri uri = Uri.CREATOR.createFromParcel(data);
-                boolean notifyForDescendents = data.readInt() != 0;
-                IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
-                registerContentObserver(uri, notifyForDescendents, observer);
-                return true;
-            }
-
-            case UNREGISTER_CHANGE_OBSERVER_TRANSACTION: {
-                IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
-                unregisterContentObserver(observer);
-                return true;
-            }
-
-            case NOTIFY_CHANGE_TRANSACTION: {
-                Uri uri = Uri.CREATOR.createFromParcel(data);
-                IContentObserver observer = IContentObserver.Stub.asInterface(data.readStrongBinder());
-                boolean observerWantsSelfNotifications = data.readInt() != 0;
-                boolean syncToNetwork = data.readInt() != 0;
-                notifyChange(uri, observer, observerWantsSelfNotifications, syncToNetwork);
-                return true;
-            }
-
-            case START_SYNC_TRANSACTION: {
-                Uri url = null;
-                int hasUrl = data.readInt();
-                if (hasUrl != 0) {
-                    url = Uri.CREATOR.createFromParcel(data);
-                }
-                startSync(url, data.readBundle());
-                return true;
-            }
-
-            case CANCEL_SYNC_TRANSACTION: {
-                Uri url = null;
-                int hasUrl = data.readInt();
-                if (hasUrl != 0) {
-                    url = Uri.CREATOR.createFromParcel(data);
-                }
-                cancelSync(url);
-                return true;
-            }
-
-            default:
-                return super.onTransact(code, data, reply, flags);
-        }
-        } catch (Exception e) {
-            Log.e("ContentServiceNative", "Caught exception in transact", e);
-        }
-
-        return false;
-    }
-
-    public IBinder asBinder()
-    {
-        return this;
-    }
-
-    private static IContentService gDefault;
-}
-
-
-final class ContentServiceProxy implements IContentService
-{
-    public ContentServiceProxy(IBinder remote)
-    {
-        mRemote = remote;
-    }
-
-    public IBinder asBinder()
-    {
-        return mRemote;
-    }
-
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            IContentObserver observer) throws RemoteException
-    {
-        Parcel data = Parcel.obtain();
-        uri.writeToParcel(data, 0);
-        data.writeInt(notifyForDescendents ? 1 : 0);
-        data.writeStrongInterface(observer);
-        mRemote.transact(REGISTER_CONTENT_OBSERVER_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-
-    public void unregisterContentObserver(IContentObserver observer) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        data.writeStrongInterface(observer);
-        mRemote.transact(UNREGISTER_CHANGE_OBSERVER_TRANSACTION, data, null, 0);
-        data.recycle();
-    }
-
-    public void notifyChange(Uri uri, IContentObserver observer,
-            boolean observerWantsSelfNotifications, boolean syncToNetwork)
-            throws RemoteException {
-        Parcel data = Parcel.obtain();
-        uri.writeToParcel(data, 0);
-        data.writeStrongInterface(observer);
-        data.writeInt(observerWantsSelfNotifications ? 1 : 0);
-        data.writeInt(syncToNetwork ? 1 : 0);
-        mRemote.transact(NOTIFY_CHANGE_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
-        data.recycle();
-    }
-
-    public void startSync(Uri url, Bundle extras) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        if (url == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            url.writeToParcel(data, 0);
-        }
-        extras.writeToParcel(data, 0);
-        mRemote.transact(START_SYNC_TRANSACTION, data, null, IBinder.FLAG_ONEWAY);
-        data.recycle();
-    }
-
-    public void cancelSync(Uri url) throws RemoteException {
-        Parcel data = Parcel.obtain();
-        if (url == null) {
-            data.writeInt(0);
-        } else {
-            data.writeInt(1);
-            url.writeToParcel(data, 0);
-        }
-        mRemote.transact(CANCEL_SYNC_TRANSACTION, data, null /* reply */, IBinder.FLAG_ONEWAY);
-        data.recycle();
-    }
-
-    private IBinder mRemote;
-}
-
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
new file mode 100644
index 0000000..8617d949
--- /dev/null
+++ b/core/java/android/content/IContentService.aidl
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.content.ActiveSyncInfo;
+import android.content.ISyncStatusObserver;
+import android.content.SyncStatusInfo;
+import android.net.Uri;
+import android.os.Bundle;
+import android.database.IContentObserver;
+
+/**
+ * @hide
+ */
+interface IContentService {
+    void registerContentObserver(in Uri uri, boolean notifyForDescendentsn,
+            IContentObserver observer);
+    void unregisterContentObserver(IContentObserver observer);
+
+    void notifyChange(in Uri uri, IContentObserver observer,
+            boolean observerWantsSelfNotifications, boolean syncToNetwork);
+
+    void startSync(in Uri url, in Bundle extras);
+    void cancelSync(in Uri uri);
+    
+    /**
+     * Check if the provider should be synced when a network tickle is received
+     * @param providerName the provider whose setting we are querying
+     * @return true of the provider should be synced when a network tickle is received
+     */
+    boolean getSyncProviderAutomatically(String providerName);
+
+    /**
+     * Set whether or not the provider is synced when it receives a network tickle.
+     *
+     * @param providerName the provider whose behavior is being controlled
+     * @param sync true if the provider should be synced when tickles are received for it
+     */
+    void setSyncProviderAutomatically(String providerName, boolean sync);
+
+    void setListenForNetworkTickles(boolean flag);
+
+    boolean getListenForNetworkTickles();
+    
+    /**
+     * Returns true if there is currently a sync operation for the given
+     * account or authority in the pending list, or actively being processed.
+     */
+    boolean isSyncActive(String account, String authority);
+    
+    ActiveSyncInfo getActiveSync();
+    
+    /**
+     * Returns the status that matches the authority. If there are multiples accounts for
+     * the authority, the one with the latest "lastSuccessTime" status is returned.
+     * @param authority the authority whose row should be selected
+     * @return the SyncStatusInfo for the authority, or null if none exists
+     */
+    SyncStatusInfo getStatusByAuthority(String authority);
+
+    /**
+     * Return true if the pending status is true of any matching authorities.
+     */
+    boolean isAuthorityPending(String account, String authority);
+    
+    void addStatusChangeListener(int mask, ISyncStatusObserver callback);
+    
+    void removeStatusChangeListener(ISyncStatusObserver callback);
+}
diff --git a/core/java/android/content/IContentService.java b/core/java/android/content/IContentService.java
deleted file mode 100644
index a3047da..0000000
--- a/core/java/android/content/IContentService.java
+++ /dev/null
@@ -1,53 +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.IContentObserver;
-import android.net.Uri;
-import android.os.RemoteException;
-import android.os.IBinder;
-import android.os.IInterface;
-import android.os.Bundle;
-
-/**
- * {@hide}
- */
-public interface IContentService extends IInterface
-{
-    public void registerContentObserver(Uri uri, boolean notifyForDescendentsn,
-            IContentObserver observer) throws RemoteException;
-    public void unregisterContentObserver(IContentObserver observer) throws RemoteException;
-
-    public void notifyChange(Uri uri, IContentObserver observer,
-            boolean observerWantsSelfNotifications, boolean syncToNetwork)
-            throws RemoteException;
-
-    public void startSync(Uri url, Bundle extras) throws RemoteException;
-    public void cancelSync(Uri uri) throws RemoteException;
-
-    static final String SERVICE_NAME = "content";
-
-    /* IPC constants */
-    static final String descriptor = "android.content.IContentService";
-
-    static final int REGISTER_CONTENT_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 1;
-    static final int UNREGISTER_CHANGE_OBSERVER_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 2;
-    static final int NOTIFY_CHANGE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 3;
-    static final int START_SYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 4;
-    static final int CANCEL_SYNC_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION + 5;
-}
-
diff --git a/core/java/android/content/ISyncStatusObserver.aidl b/core/java/android/content/ISyncStatusObserver.aidl
new file mode 100644
index 0000000..eb26845
--- /dev/null
+++ b/core/java/android/content/ISyncStatusObserver.aidl
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+/**
+ * @hide
+ */
+oneway interface ISyncStatusObserver {
+    void onStatusChanged(int which);
+}
diff --git a/core/java/android/content/SyncManager.java b/core/java/android/content/SyncManager.java
index 96470c3..ade5f3d 100644
--- a/core/java/android/content/SyncManager.java
+++ b/core/java/android/content/SyncManager.java
@@ -32,8 +32,6 @@
 import android.content.pm.PackageManager;
 import android.content.pm.ProviderInfo;
 import android.content.pm.ResolveInfo;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
 import android.net.ConnectivityManager;
 import android.net.NetworkInfo;
 import android.net.Uri;
@@ -43,18 +41,13 @@
 import android.os.IBinder;
 import android.os.Looper;
 import android.os.Message;
-import android.os.Parcel;
 import android.os.PowerManager;
 import android.os.Process;
 import android.os.RemoteException;
 import android.os.ServiceManager;
 import android.os.SystemClock;
 import android.os.SystemProperties;
-import android.preference.Preference;
-import android.preference.PreferenceGroup;
-import android.provider.Sync;
 import android.provider.Settings;
-import android.provider.Sync.History;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.text.format.Time;
@@ -73,13 +66,12 @@
 import java.io.PrintWriter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.PriorityQueue;
 import java.util.Random;
-import java.util.Observer;
-import java.util.Observable;
 
 /**
  * @hide
@@ -138,7 +130,6 @@
     volatile private PowerManager.WakeLock mHandleAlarmWakeLock;
     volatile private boolean mDataConnectionIsConnected = false;
     volatile private boolean mStorageIsLow = false;
-    private Sync.Settings.QueryMap mSyncSettings;
 
     private final NotificationManager mNotificationMgr;
     private AlarmManager mAlarmService = null;
@@ -225,17 +216,6 @@
     private static final String SYNC_POLL_ALARM = "android.content.syncmanager.SYNC_POLL_ALARM";
     private final SyncHandler mSyncHandler;
 
-    private static final String[] SYNC_ACTIVE_PROJECTION = new String[]{
-            Sync.Active.ACCOUNT,
-            Sync.Active.AUTHORITY,
-            Sync.Active.START_TIME,
-    };
-
-    private static final String[] SYNC_PENDING_PROJECTION = new String[]{
-            Sync.Pending.ACCOUNT,
-            Sync.Pending.AUTHORITY
-    };
-
     private static final int MAX_SYNC_POLL_DELAY_SECONDS = 36 * 60 * 60; // 36 hours
     private static final int MIN_SYNC_POLL_DELAY_SECONDS = 24 * 60 * 60; // 24 hours
 
@@ -289,6 +269,14 @@
                 HANDLE_SYNC_ALARM_WAKE_LOCK);
         mHandleAlarmWakeLock.setReferenceCounted(false);
 
+        mSyncStorageEngine.addStatusChangeListener(
+                SyncStorageEngine.CHANGE_SETTINGS, new ISyncStatusObserver.Stub() {
+            public void onStatusChanged(int which) {
+                // force the sync loop to run if the settings change
+                sendCheckAlarmsMessage();
+            }
+        });
+        
         if (!factoryTest) {
             AccountMonitorListener listener = new AccountMonitorListener() {
                 public void onAccountsUpdated(String[] accounts) {
@@ -448,20 +436,10 @@
         return mActiveSyncContext;
     }
 
-    private Sync.Settings.QueryMap getSyncSettings() {
-        if (mSyncSettings == null) {
-            mSyncSettings = new Sync.Settings.QueryMap(mContext.getContentResolver(), true,
-                    new Handler());
-            mSyncSettings.addObserver(new Observer(){
-                public void update(Observable o, Object arg) {
-                    // force the sync loop to run if the settings change
-                    sendCheckAlarmsMessage();
-                }
-            });
-        }
-        return mSyncSettings;
+    public SyncStorageEngine getSyncStorageEngine() {
+        return mSyncStorageEngine;
     }
-
+    
     private void ensureContentResolver() {
         if (mContentResolver == null) {
             mContentResolver = mContext.getContentResolver();
@@ -574,15 +552,15 @@
 
         int source;
         if (uploadOnly) {
-            source = Sync.History.SOURCE_LOCAL;
+            source = SyncStorageEngine.SOURCE_LOCAL;
         } else if (force) {
-            source = Sync.History.SOURCE_USER;
+            source = SyncStorageEngine.SOURCE_USER;
         } else if (url == null) {
-            source = Sync.History.SOURCE_POLL;
+            source = SyncStorageEngine.SOURCE_POLL;
         } else {
             // this isn't strictly server, since arbitrary callers can (and do) request
             // a non-forced two-way sync on a specific url
-            source = Sync.History.SOURCE_SERVER;
+            source = SyncStorageEngine.SOURCE_SERVER;
         }
 
         List<String> names = new ArrayList<String>();
@@ -667,9 +645,7 @@
 
     public void updateHeartbeatTime() {
         mHeartbeatTime = SystemClock.elapsedRealtime();
-        ensureContentResolver();
-        mContentResolver.notifyChange(Sync.Active.CONTENT_URI,
-                null /* this change wasn't made through an observer */);
+        mSyncStorageEngine.reportActiveChange();
     }
 
     private void sendSyncAlarmMessage() {
@@ -876,7 +852,7 @@
         final String key;
         long earliestRunTime;
         long delay;
-        Long rowId = null;
+        SyncStorageEngine.PendingOperation pendingOperation;
 
         SyncOperation(String account, int source, String authority, Bundle extras, long delay) {
             this.account = account;
@@ -916,7 +892,7 @@
             sb.append(" when: ").append(earliestRunTime);
             sb.append(" delay: ").append(delay);
             sb.append(" key: {").append(key).append("}");
-            if (rowId != null) sb.append(" rowId: ").append(rowId);
+            if (pendingOperation != null) sb.append(" pendingOperation: ").append(pendingOperation);
             return sb.toString();
         }
 
@@ -999,242 +975,262 @@
 
     protected void dump(FileDescriptor fd, PrintWriter pw) {
         StringBuilder sb = new StringBuilder();
-        dumpSyncState(sb);
-        sb.append("\n");
+        dumpSyncState(pw, sb);
         if (isSyncEnabled()) {
-            dumpSyncHistory(sb);
+            dumpSyncHistory(pw, sb);
         }
-        pw.println(sb.toString());
     }
 
-    protected void dumpSyncState(StringBuilder sb) {
-        sb.append("sync enabled: ").append(isSyncEnabled()).append("\n");
-        sb.append("data connected: ").append(mDataConnectionIsConnected).append("\n");
-        sb.append("memory low: ").append(mStorageIsLow).append("\n");
+    static String formatTime(long time) {
+        Time tobj = new Time();
+        tobj.set(time);
+        return tobj.format("%Y-%m-%d %H:%M:%S");
+    }
+    
+    protected void dumpSyncState(PrintWriter pw, StringBuilder sb) {
+        pw.print("sync enabled: "); pw.println(isSyncEnabled());
+        pw.print("data connected: "); pw.println(mDataConnectionIsConnected);
+        pw.print("memory low: "); pw.println(mStorageIsLow);
 
         final String[] accounts = mAccounts;
-        sb.append("accounts: ");
+        pw.print("accounts: ");
         if (accounts != null) {
-            sb.append(accounts.length);
+            pw.println(accounts.length);
         } else {
-            sb.append("none");
+            pw.println("none");
         }
-        sb.append("\n");
         final long now = SystemClock.elapsedRealtime();
-        sb.append("now: ").append(now).append("\n");
-        sb.append("uptime: ").append(DateUtils.formatElapsedTime(now/1000)).append(" (HH:MM:SS)\n");
-        sb.append("time spent syncing : ")
-                .append(DateUtils.formatElapsedTime(
-                        mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000))
-                .append(" (HH:MM:SS), sync ")
-                .append(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not ")
-                .append("in progress").append("\n");
+        pw.print("now: "); pw.println(now);
+        pw.print("uptime: "); pw.print(DateUtils.formatElapsedTime(now/1000));
+                pw.println(" (HH:MM:SS)");
+        pw.print("time spent syncing: ");
+                pw.print(DateUtils.formatElapsedTime(
+                        mSyncHandler.mSyncTimeTracker.timeSpentSyncing() / 1000));
+                pw.print(" (HH:MM:SS), sync ");
+                pw.print(mSyncHandler.mSyncTimeTracker.mLastWasSyncing ? "" : "not ");
+                pw.println("in progress");
         if (mSyncHandler.mAlarmScheduleTime != null) {
-            sb.append("next alarm time: ").append(mSyncHandler.mAlarmScheduleTime)
-                    .append(" (")
-                    .append(DateUtils.formatElapsedTime((mSyncHandler.mAlarmScheduleTime-now)/1000))
-                    .append(" (HH:MM:SS) from now)\n");
+            pw.print("next alarm time: "); pw.print(mSyncHandler.mAlarmScheduleTime);
+                    pw.print(" (");
+                    pw.print(DateUtils.formatElapsedTime((mSyncHandler.mAlarmScheduleTime-now)/1000));
+                    pw.println(" (HH:MM:SS) from now)");
         } else {
-            sb.append("no alarm is scheduled (there had better not be any pending syncs)\n");
+            pw.println("no alarm is scheduled (there had better not be any pending syncs)");
         }
 
-        sb.append("active sync: ").append(mActiveSyncContext).append("\n");
+        pw.print("active sync: "); pw.println(mActiveSyncContext);
 
-        sb.append("notification info: ");
+        pw.print("notification info: ");
+        sb.setLength(0);
         mSyncHandler.mSyncNotificationInfo.toString(sb);
-        sb.append("\n");
+        pw.println(sb.toString());
 
         synchronized (mSyncQueue) {
-            sb.append("sync queue: ");
+            pw.print("sync queue: ");
+            sb.setLength(0);
             mSyncQueue.dump(sb);
+            pw.println(sb.toString());
         }
 
-        Cursor c = mSyncStorageEngine.query(Sync.Active.CONTENT_URI,
-                SYNC_ACTIVE_PROJECTION, null, null, null);
-        sb.append("\n");
-        try {
-            if (c.moveToNext()) {
-                final long durationInSeconds = (now - c.getLong(2)) / 1000;
-                sb.append("Active sync: ").append(c.getString(0))
-                        .append(" ").append(c.getString(1))
-                        .append(", duration is ")
-                        .append(DateUtils.formatElapsedTime(durationInSeconds)).append(".\n");
-            } else {
-                sb.append("No sync is in progress.\n");
-            }
-        } finally {
-            c.close();
-        }
-
-        c = mSyncStorageEngine.query(Sync.Pending.CONTENT_URI,
-                SYNC_PENDING_PROJECTION, null, null, "account, authority");
-        sb.append("\nPending Syncs\n");
-        try {
-            if (c.getCount() != 0) {
-                dumpSyncPendingHeader(sb);
-                while (c.moveToNext()) {
-                    dumpSyncPendingRow(sb, c);
-                }
-                dumpSyncPendingFooter(sb);
-            } else {
-                sb.append("none\n");
-            }
-        } finally {
-            c.close();
-        }
-
-        String currentAccount = null;
-        c = mSyncStorageEngine.query(Sync.Status.CONTENT_URI,
-                STATUS_PROJECTION, null, null, "account, authority");
-        sb.append("\nSync history by account and authority\n");
-        try {
-            while (c.moveToNext()) {
-                if (!TextUtils.equals(currentAccount, c.getString(0))) {
-                    if (currentAccount != null) {
-                        dumpSyncHistoryFooter(sb);
-                    }
-                    currentAccount = c.getString(0);
-                    dumpSyncHistoryHeader(sb, currentAccount);
-                }
-
-                dumpSyncHistoryRow(sb, c);
-            }
-            if (c.getCount() > 0) dumpSyncHistoryFooter(sb);
-        } finally {
-            c.close();
-        }
-    }
-
-    private void dumpSyncHistoryHeader(StringBuilder sb, String account) {
-        sb.append(" Account: ").append(account).append("\n");
-        sb.append("  ___________________________________________________________________________________________________________________________\n");
-        sb.append(" |                 |             num times synced           |   total  |         last success          |                     |\n");
-        sb.append(" | authority       | local |  poll | server |  user | total | duration |  source |               time  |   result if failing |\n");
-    }
-
-    private static String[] STATUS_PROJECTION = new String[]{
-            Sync.Status.ACCOUNT, // 0
-            Sync.Status.AUTHORITY, // 1
-            Sync.Status.NUM_SYNCS, // 2
-            Sync.Status.TOTAL_ELAPSED_TIME, // 3
-            Sync.Status.NUM_SOURCE_LOCAL, // 4
-            Sync.Status.NUM_SOURCE_POLL, // 5
-            Sync.Status.NUM_SOURCE_SERVER, // 6
-            Sync.Status.NUM_SOURCE_USER, // 7
-            Sync.Status.LAST_SUCCESS_SOURCE, // 8
-            Sync.Status.LAST_SUCCESS_TIME, // 9
-            Sync.Status.LAST_FAILURE_SOURCE, // 10
-            Sync.Status.LAST_FAILURE_TIME, // 11
-            Sync.Status.LAST_FAILURE_MESG // 12
-    };
-
-    private void dumpSyncHistoryRow(StringBuilder sb, Cursor c) {
-        boolean hasSuccess = !c.isNull(9);
-        boolean hasFailure = !c.isNull(11);
-        Time timeSuccess = new Time();
-        if (hasSuccess) timeSuccess.set(c.getLong(9));
-        Time timeFailure = new Time();
-        if (hasFailure) timeFailure.set(c.getLong(11));
-        sb.append(String.format(" | %-15s | %5d | %5d | %6d | %5d | %5d | %8s | %7s | %19s | %19s |\n",
-                c.getString(1),
-                c.getLong(4),
-                c.getLong(5),
-                c.getLong(6),
-                c.getLong(7),
-                c.getLong(2),
-                DateUtils.formatElapsedTime(c.getLong(3)/1000),
-                hasSuccess ? Sync.History.SOURCES[c.getInt(8)] : "",
-                hasSuccess ? timeSuccess.format("%Y-%m-%d %H:%M:%S") : "",
-                hasFailure ? History.mesgToString(c.getString(12)) : ""));
-    }
-
-    private void dumpSyncHistoryFooter(StringBuilder sb) {
-        sb.append(" |___________________________________________________________________________________________________________________________|\n");
-    }
-
-    private void dumpSyncPendingHeader(StringBuilder sb) {
-        sb.append(" ____________________________________________________\n");
-        sb.append(" | account                        | authority       |\n");
-    }
-
-    private void dumpSyncPendingRow(StringBuilder sb, Cursor c) {
-        sb.append(String.format(" | %-30s | %-15s |\n", c.getString(0), c.getString(1)));
-    }
-
-    private void dumpSyncPendingFooter(StringBuilder sb) {
-        sb.append(" |__________________________________________________|\n");
-    }
-
-    protected void dumpSyncHistory(StringBuilder sb) {
-        Cursor c = mSyncStorageEngine.query(Sync.History.CONTENT_URI, null, "event=?",
-                new String[]{String.valueOf(Sync.History.EVENT_STOP)},
-                Sync.HistoryColumns.EVENT_TIME + " desc");
-        try {
-            long numSyncsLastHour = 0, durationLastHour = 0;
-            long numSyncsLastDay = 0, durationLastDay = 0;
-            long numSyncsLastWeek = 0, durationLastWeek = 0;
-            long numSyncsLast4Weeks = 0, durationLast4Weeks = 0;
-            long numSyncsTotal = 0, durationTotal = 0;
-
-            long now = System.currentTimeMillis();
-            int indexEventTime = c.getColumnIndexOrThrow(Sync.History.EVENT_TIME);
-            int indexElapsedTime = c.getColumnIndexOrThrow(Sync.History.ELAPSED_TIME);
-            while (c.moveToNext()) {
-                long duration = c.getLong(indexElapsedTime);
-                long endTime = c.getLong(indexEventTime) + duration;
-                long millisSinceStart = now - endTime;
-                numSyncsTotal++;
-                durationTotal += duration;
-                if (millisSinceStart < MILLIS_IN_HOUR) {
-                    numSyncsLastHour++;
-                    durationLastHour += duration;
-                }
-                if (millisSinceStart < MILLIS_IN_DAY) {
-                    numSyncsLastDay++;
-                    durationLastDay += duration;
-                }
-                if (millisSinceStart < MILLIS_IN_WEEK) {
-                    numSyncsLastWeek++;
-                    durationLastWeek += duration;
-                }
-                if (millisSinceStart < MILLIS_IN_4WEEKS) {
-                    numSyncsLast4Weeks++;
-                    durationLast4Weeks += duration;
-                }
-            }
-            dumpSyncIntervalHeader(sb);
-            dumpSyncInterval(sb, "hour", MILLIS_IN_HOUR, numSyncsLastHour, durationLastHour);
-            dumpSyncInterval(sb, "day", MILLIS_IN_DAY, numSyncsLastDay, durationLastDay);
-            dumpSyncInterval(sb, "week", MILLIS_IN_WEEK, numSyncsLastWeek, durationLastWeek);
-            dumpSyncInterval(sb, "4 weeks",
-                    MILLIS_IN_4WEEKS, numSyncsLast4Weeks, durationLast4Weeks);
-            dumpSyncInterval(sb, "total", 0, numSyncsTotal, durationTotal);
-            dumpSyncIntervalFooter(sb);
-        } finally {
-            c.close();
-        }
-    }
-
-    private void dumpSyncIntervalHeader(StringBuilder sb) {
-        sb.append("Sync Stats\n");
-        sb.append(" ___________________________________________________________\n");
-        sb.append(" |          |        |   duration in sec   |               |\n");
-        sb.append(" | interval |  count |  average |    total | % of interval |\n");
-    }
-
-    private void dumpSyncInterval(StringBuilder sb, String label,
-            long interval, long numSyncs, long duration) {
-        sb.append(String.format(" | %-8s | %6d | %8.1f | %8.1f",
-                label, numSyncs, ((float)duration/numSyncs)/1000, (float)duration/1000));
-        if (interval > 0) {
-            sb.append(String.format(" | %13.2f |\n", ((float)duration/interval)*100.0));
+        ActiveSyncInfo active = mSyncStorageEngine.getActiveSync();
+        if (active != null) {
+            SyncStorageEngine.AuthorityInfo authority
+                    = mSyncStorageEngine.getAuthority(active.authorityId);
+            final long durationInSeconds = (now - active.startTime) / 1000;
+            pw.print("Active sync: ");
+                    pw.print(authority != null ? authority.account : "<no account>");
+                    pw.print(" ");
+                    pw.print(authority != null ? authority.authority : "<no account>");
+                    pw.print(", duration is ");
+                    pw.println(DateUtils.formatElapsedTime(durationInSeconds));
         } else {
-            sb.append(String.format(" | %13s |\n", "na"));
+            pw.println("No sync is in progress.");
+        }
+
+        ArrayList<SyncStorageEngine.PendingOperation> ops
+                = mSyncStorageEngine.getPendingOperations();
+        if (ops != null && ops.size() > 0) {
+            pw.println();
+            pw.println("Pending Syncs");
+            final int N = ops.size();
+            for (int i=0; i<N; i++) {
+                SyncStorageEngine.PendingOperation op = ops.get(i);
+                pw.print("  #"); pw.print(i); pw.print(": account=");
+                pw.print(op.account); pw.print(" authority=");
+                pw.println(op.authority);
+                if (op.extras != null && op.extras.size() > 0) {
+                    sb.setLength(0);
+                    SyncOperation.extrasToStringBuilder(op.extras, sb);
+                    pw.print("    extras: "); pw.println(sb.toString());
+                }
+            }
+        }
+
+        HashSet<String> processedAccounts = new HashSet<String>();
+        ArrayList<SyncStatusInfo> statuses
+                = mSyncStorageEngine.getSyncStatus();
+        if (statuses != null && statuses.size() > 0) {
+            pw.println();
+            pw.println("Sync Status");
+            final int N = statuses.size();
+            for (int i=0; i<N; i++) {
+                SyncStatusInfo status = statuses.get(i);
+                SyncStorageEngine.AuthorityInfo authority
+                        = mSyncStorageEngine.getAuthority(status.authorityId);
+                if (authority != null) {
+                    String curAccount = authority.account;
+                    
+                    if (processedAccounts.contains(curAccount)) {
+                        continue;
+                    }
+                    
+                    processedAccounts.add(curAccount);
+                    
+                    pw.print("  Account "); pw.print(authority.account);
+                    pw.println(":");
+                    for (int j=i; j<N; j++) {
+                        status = statuses.get(j);
+                        authority = mSyncStorageEngine.getAuthority(status.authorityId);
+                        if (!curAccount.equals(authority.account)) {
+                            continue;
+                        }
+                        pw.print("    "); pw.print(authority.authority);
+                        pw.println(":");
+                        pw.print("      count: local="); pw.print(status.numSourceLocal);
+                                pw.print(" poll="); pw.print(status.numSourcePoll);
+                                pw.print(" server="); pw.print(status.numSourceServer);
+                                pw.print(" user="); pw.print(status.numSourceUser);
+                                pw.print(" total="); pw.println(status.numSyncs);
+                        pw.print("      total duration: ");
+                                pw.println(DateUtils.formatElapsedTime(
+                                        status.totalElapsedTime/1000));
+                        if (status.lastSuccessTime != 0) {
+                            pw.print("      SUCCESS: source=");
+                                    pw.print(SyncStorageEngine.SOURCES[
+                                            status.lastSuccessSource]);
+                                    pw.print(" time=");
+                                    pw.println(formatTime(status.lastSuccessTime));
+                        } else {
+                            pw.print("      FAILURE: source=");
+                                    pw.print(SyncStorageEngine.SOURCES[
+                                            status.lastFailureSource]);
+                                    pw.print(" initialTime=");
+                                    pw.print(formatTime(status.initialFailureTime));
+                                    pw.print(" lastTime=");
+                                    pw.println(formatTime(status.lastFailureTime));
+                            pw.print("      message: "); pw.println(status.lastFailureMesg);
+                        }
+                    }
+                }
+            }
         }
     }
 
-    private void dumpSyncIntervalFooter(StringBuilder sb) {
-        sb.append(" |_________________________________________________________|\n");
+    private void dumpTimeSec(PrintWriter pw, long time) {
+        pw.print(time/1000); pw.print('.'); pw.print((time/100)%10);
+        pw.print('s');
+    }
+    
+    private void dumpDayStatistic(PrintWriter pw, SyncStorageEngine.DayStats ds) {
+        pw.print("Success ("); pw.print(ds.successCount);
+        if (ds.successCount > 0) {
+            pw.print(" for "); dumpTimeSec(pw, ds.successTime);
+            pw.print(" avg="); dumpTimeSec(pw, ds.successTime/ds.successCount);
+        }
+        pw.print(") Failure ("); pw.print(ds.failureCount);
+        if (ds.failureCount > 0) {
+            pw.print(" for "); dumpTimeSec(pw, ds.failureTime);
+            pw.print(" avg="); dumpTimeSec(pw, ds.failureTime/ds.failureCount);
+        }
+        pw.println(")");
+    }
+    
+    protected void dumpSyncHistory(PrintWriter pw, StringBuilder sb) {
+        SyncStorageEngine.DayStats dses[] = mSyncStorageEngine.getDayStatistics();
+        if (dses != null && dses[0] != null) {
+            pw.println();
+            pw.println("Sync Statistics");
+            pw.print("  Today:  "); dumpDayStatistic(pw, dses[0]);
+            int today = dses[0].day;
+            int i;
+            SyncStorageEngine.DayStats ds;
+            
+            // Print each day in the current week.
+            for (i=1; i<=6 && i < dses.length; i++) {
+                ds = dses[i];
+                if (ds == null) break;
+                int delta = today-ds.day;
+                if (delta > 6) break;
+                
+                pw.print("  Day-"); pw.print(delta); pw.print(":  ");
+                dumpDayStatistic(pw, ds);
+            }
+            
+            // Aggregate all following days into weeks and print totals.
+            int weekDay = today;
+            while (i < dses.length) {
+                SyncStorageEngine.DayStats aggr = null;
+                weekDay -= 7;
+                while (i < dses.length) {
+                    ds = dses[i];
+                    if (ds == null) {
+                        i = dses.length;
+                        break;
+                    }
+                    int delta = weekDay-ds.day;
+                    if (delta > 6) break;
+                    i++;
+                    
+                    if (aggr == null) {
+                        aggr = new SyncStorageEngine.DayStats(weekDay);
+                    }
+                    aggr.successCount += ds.successCount;
+                    aggr.successTime += ds.successTime;
+                    aggr.failureCount += ds.failureCount;
+                    aggr.failureTime += ds.failureTime;
+                }
+                if (aggr != null) {
+                    pw.print("  Week-"); pw.print((today-weekDay)/7); pw.print(": ");
+                    dumpDayStatistic(pw, aggr);
+                }
+            }
+        }
+        
+        ArrayList<SyncStorageEngine.SyncHistoryItem> items
+                = mSyncStorageEngine.getSyncHistory();
+        if (items != null && items.size() > 0) {
+            pw.println();
+            pw.println("Recent Sync History");
+            final int N = items.size();
+            for (int i=0; i<N; i++) {
+                SyncStorageEngine.SyncHistoryItem item = items.get(i);
+                SyncStorageEngine.AuthorityInfo authority
+                        = mSyncStorageEngine.getAuthority(item.authorityId);
+                pw.print("  #"); pw.print(i+1); pw.print(": ");
+                        pw.print(authority != null ? authority.account : "<no account>");
+                        pw.print(" ");
+                        pw.print(authority != null ? authority.authority : "<no account>");
+                Time time = new Time();
+                time.set(item.eventTime);
+                pw.print(" "); pw.print(SyncStorageEngine.SOURCES[item.source]);
+                        pw.print(" @ ");
+                        pw.print(formatTime(item.eventTime));
+                        pw.print(" for ");
+                        dumpTimeSec(pw, item.elapsedTime);
+                        pw.println();
+                if (item.event != SyncStorageEngine.EVENT_STOP
+                        || item.upstreamActivity !=0
+                        || item.downstreamActivity != 0) {
+                    pw.print("    event="); pw.print(item.event);
+                            pw.print(" upstreamActivity="); pw.print(item.upstreamActivity);
+                            pw.print(" downstreamActivity="); pw.println(item.downstreamActivity);
+                }
+                if (item.mesg != null
+                        && !SyncStorageEngine.MESG_SUCCESS.equals(item.mesg)) {
+                    pw.print("    mesg="); pw.println(item.mesg);
+                }
+            }
+        }
     }
 
     /**
@@ -1461,7 +1457,6 @@
             // found that is runnable (not disabled, etc). If that one is ready to run then
             // start it, otherwise just get out.
             SyncOperation syncOperation;
-            final Sync.Settings.QueryMap syncSettings = getSyncSettings();
             final ConnectivityManager connManager = (ConnectivityManager)
                     mContext.getSystemService(Context.CONNECTIVITY_SERVICE);
             final boolean backgroundDataSetting = connManager.getBackgroundDataSetting();
@@ -1488,9 +1483,9 @@
                     final boolean force = syncOperation.extras.getBoolean(
                             ContentResolver.SYNC_EXTRAS_FORCE, false);
                     if (!force && (!backgroundDataSetting
-                            || !syncSettings.getListenForNetworkTickles()
-                            || !syncSettings.getSyncProviderAutomatically(
-                                    syncOperation.authority))) {
+                            || !mSyncStorageEngine.getListenForNetworkTickles()
+                            || !mSyncStorageEngine.getSyncProviderAutomatically(
+                                    null, syncOperation.authority))) {
                         if (isLoggable) {
                             Log.v(TAG, "runStateIdle: sync off, dropping " + syncOperation);
                         }
@@ -1616,7 +1611,7 @@
                     if (isLoggable) {
                         Log.v(TAG, "finished sync operation " + syncOperation);
                     }
-                    historyMessage = History.MESG_SUCCESS;
+                    historyMessage = SyncStorageEngine.MESG_SUCCESS;
                     // TODO: set these correctly when the SyncResult is extended to include it
                     downstreamActivity = 0;
                     upstreamActivity = 0;
@@ -1640,7 +1635,7 @@
                 } catch (RemoteException e) {
                     // we don't need to retry this in this case
                 }
-                historyMessage = History.MESG_CANCELED;
+                historyMessage = SyncStorageEngine.MESG_CANCELED;
                 downstreamActivity = 0;
                 upstreamActivity = 0;
             }
@@ -1675,14 +1670,22 @@
          *   If SyncResult.error() is true then it is safe to call this.
          */
         private int syncResultToErrorNumber(SyncResult syncResult) {
-            if (syncResult.syncAlreadyInProgress) return History.ERROR_SYNC_ALREADY_IN_PROGRESS;
-            if (syncResult.stats.numAuthExceptions > 0) return History.ERROR_AUTHENTICATION;
-            if (syncResult.stats.numIoExceptions > 0) return History.ERROR_IO;
-            if (syncResult.stats.numParseExceptions > 0) return History.ERROR_PARSE;
-            if (syncResult.stats.numConflictDetectedExceptions > 0) return History.ERROR_CONFLICT;
-            if (syncResult.tooManyDeletions) return History.ERROR_TOO_MANY_DELETIONS;
-            if (syncResult.tooManyRetries) return History.ERROR_TOO_MANY_RETRIES;
-            if (syncResult.databaseError) return History.ERROR_INTERNAL;
+            if (syncResult.syncAlreadyInProgress)
+                return SyncStorageEngine.ERROR_SYNC_ALREADY_IN_PROGRESS;
+            if (syncResult.stats.numAuthExceptions > 0)
+                return SyncStorageEngine.ERROR_AUTHENTICATION;
+            if (syncResult.stats.numIoExceptions > 0)
+                return SyncStorageEngine.ERROR_IO;
+            if (syncResult.stats.numParseExceptions > 0)
+                return SyncStorageEngine.ERROR_PARSE;
+            if (syncResult.stats.numConflictDetectedExceptions > 0)
+                return SyncStorageEngine.ERROR_CONFLICT;
+            if (syncResult.tooManyDeletions)
+                return SyncStorageEngine.ERROR_TOO_MANY_DELETIONS;
+            if (syncResult.tooManyRetries)
+                return SyncStorageEngine.ERROR_TOO_MANY_RETRIES;
+            if (syncResult.databaseError)
+                return SyncStorageEngine.ERROR_INTERNAL;
             throw new IllegalStateException("we are not in an error state, " + syncResult);
         }
 
@@ -1904,7 +1907,8 @@
             final int source = syncOperation.syncSource;
             final long now = System.currentTimeMillis();
 
-            EventLog.writeEvent(2720, syncOperation.authority, Sync.History.EVENT_START, source);
+            EventLog.writeEvent(2720, syncOperation.authority,
+                    SyncStorageEngine.EVENT_START, source);
 
             return mSyncStorageEngine.insertStartSyncEvent(
                     syncOperation.account, syncOperation.authority, now, source);
@@ -1912,7 +1916,8 @@
 
         public void stopSyncEvent(long rowId, SyncOperation syncOperation, String resultMessage,
                 int upstreamActivity, int downstreamActivity, long elapsedTime) {
-            EventLog.writeEvent(2720, syncOperation.authority, Sync.History.EVENT_STOP, syncOperation.syncSource);
+            EventLog.writeEvent(2720, syncOperation.authority,
+                    SyncStorageEngine.EVENT_STOP, syncOperation.syncSource);
 
             mSyncStorageEngine.stopSyncEvent(rowId, elapsedTime, resultMessage,
                     downstreamActivity, upstreamActivity);
@@ -1921,18 +1926,6 @@
 
     static class SyncQueue {
         private SyncStorageEngine mSyncStorageEngine;
-        private final String[] COLUMNS = new String[]{
-                "_id",
-                "authority",
-                "account",
-                "extras",
-                "source"
-        };
-        private static final int COLUMN_ID = 0;
-        private static final int COLUMN_AUTHORITY = 1;
-        private static final int COLUMN_ACCOUNT = 2;
-        private static final int COLUMN_EXTRAS = 3;
-        private static final int COLUMN_SOURCE = 4;
 
         private static final boolean DEBUG_CHECK_DATA_CONSISTENCY = false;
 
@@ -1946,25 +1939,28 @@
 
         public SyncQueue(SyncStorageEngine syncStorageEngine) {
             mSyncStorageEngine = syncStorageEngine;
-            Cursor cursor = mSyncStorageEngine.getPendingSyncsCursor(COLUMNS);
-            try {
-                while (cursor.moveToNext()) {
-                    add(cursorToOperation(cursor),
-                            true /* this is being added from the database */);
-                }
-            } finally {
-                cursor.close();
-                if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
+            ArrayList<SyncStorageEngine.PendingOperation> ops
+                    = mSyncStorageEngine.getPendingOperations();
+            final int N = ops.size();
+            for (int i=0; i<N; i++) {
+                SyncStorageEngine.PendingOperation op = ops.get(i);
+                SyncOperation syncOperation = new SyncOperation(
+                        op.account, op.syncSource, op.authority, op.extras, 0);
+                syncOperation.pendingOperation = op;
+                add(syncOperation, op);
             }
+            
+            if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(true /* check the DB */);
         }
 
         public boolean add(SyncOperation operation) {
             return add(new SyncOperation(operation),
-                    false /* this is not coming from the database */);
+                    null /* this is not coming from the database */);
         }
 
-        private boolean add(SyncOperation operation, boolean fromDatabase) {
-            if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
+        private boolean add(SyncOperation operation,
+                SyncStorageEngine.PendingOperation pop) {
+            if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(pop == null);
 
             // If this operation is expedited then set its earliestRunTime to be immediately
             // before the head of the list, or not if none are in the list.
@@ -1996,7 +1992,7 @@
 
             if (existingOperation != null
                     && operation.earliestRunTime >= existingOperation.earliestRunTime) {
-                if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
+                if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(pop == null);
                 return false;
             }
 
@@ -2004,26 +2000,17 @@
                 removeByKey(operationKey);
             }
 
-            if (operation.rowId == null) {
-                byte[] extrasData = null;
-                Parcel parcel = Parcel.obtain();
-                try {
-                    operation.extras.writeToParcel(parcel, 0);
-                    extrasData = parcel.marshall();
-                } finally {
-                    parcel.recycle();
-                }
-                ContentValues values = new ContentValues();
-                values.put("account", operation.account);
-                values.put("authority", operation.authority);
-                values.put("source", operation.syncSource);
-                values.put("extras", extrasData);
-                Uri pendingUri = mSyncStorageEngine.insertIntoPending(values);
-                operation.rowId = pendingUri == null ? null : ContentUris.parseId(pendingUri);
-                if (operation.rowId == null) {
+            operation.pendingOperation = pop;
+            if (operation.pendingOperation == null) {
+                pop = new SyncStorageEngine.PendingOperation(
+                                operation.account, operation.syncSource,
+                                operation.authority, operation.extras);
+                pop = mSyncStorageEngine.insertIntoPending(pop);
+                if (pop == null) {
                     throw new IllegalStateException("error adding pending sync operation "
                             + operation);
                 }
+                operation.pendingOperation = pop;
             }
 
             if (DEBUG_CHECK_DATA_CONSISTENCY) {
@@ -2033,7 +2020,7 @@
             }
             mOpsByKey.put(operationKey, operation);
             mOpsByWhen.add(operation);
-            if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(!fromDatabase);
+            if (DEBUG_CHECK_DATA_CONSISTENCY) debugCheckDataStructures(pop == null);
             return true;
         }
 
@@ -2045,7 +2032,7 @@
                         "unable to find " + operationToRemove + " in mOpsByWhen");
             }
 
-            if (mSyncStorageEngine.deleteFromPending(operationToRemove.rowId) != 1) {
+            if (!mSyncStorageEngine.deleteFromPending(operationToRemove.pendingOperation)) {
                 throw new IllegalStateException("unable to find pending row for "
                         + operationToRemove);
             }
@@ -2065,7 +2052,7 @@
                 throw new IllegalStateException("unable to find " + operation + " in mOpsByKey");
             }
 
-            if (mSyncStorageEngine.deleteFromPending(operation.rowId) != 1) {
+            if (!mSyncStorageEngine.deleteFromPending(operation.pendingOperation)) {
                 throw new IllegalStateException("unable to find pending row for " + operation);
             }
 
@@ -2087,7 +2074,7 @@
                             "unable to find " + syncOperation + " in mOpsByWhen");
                 }
 
-                if (mSyncStorageEngine.deleteFromPending(syncOperation.rowId) != 1) {
+                if (!mSyncStorageEngine.deleteFromPending(syncOperation.pendingOperation)) {
                     throw new IllegalStateException("unable to find pending row for "
                             + syncOperation);
                 }
@@ -2128,48 +2115,29 @@
             }
 
             if (checkDatabase) {
-                // check that the DB contains the same rows as the in-memory data structures
-                Cursor cursor = mSyncStorageEngine.getPendingSyncsCursor(COLUMNS);
-                try {
-                    if (mOpsByKey.size() != cursor.getCount()) {
-                        StringBuilder sb = new StringBuilder();
-                        DatabaseUtils.dumpCursor(cursor, sb);
+                final int N = mSyncStorageEngine.getPendingOperationCount();
+                if (mOpsByKey.size() != N) {
+                    ArrayList<SyncStorageEngine.PendingOperation> ops
+                            = mSyncStorageEngine.getPendingOperations();
+                    StringBuilder sb = new StringBuilder();
+                    for (int i=0; i<N; i++) {
+                        SyncStorageEngine.PendingOperation op = ops.get(i);
+                        sb.append("#");
+                        sb.append(i);
+                        sb.append(": account=");
+                        sb.append(op.account);
+                        sb.append(" syncSource=");
+                        sb.append(op.syncSource);
+                        sb.append(" authority=");
+                        sb.append(op.authority);
                         sb.append("\n");
-                        dump(sb);
-                        throw new IllegalStateException("DB size mismatch: "
-                                + mOpsByKey .size() + " != " + cursor.getCount() + "\n"
-                                + sb.toString());
                     }
-                } finally {
-                    cursor.close();
+                    dump(sb);
+                    throw new IllegalStateException("DB size mismatch: "
+                            + mOpsByKey.size() + " != " + N + "\n"
+                            + sb.toString());
                 }
             }
         }
-
-        private SyncOperation cursorToOperation(Cursor cursor) {
-            byte[] extrasData = cursor.getBlob(COLUMN_EXTRAS);
-            Bundle extras;
-            Parcel parcel = Parcel.obtain();
-            try {
-                parcel.unmarshall(extrasData, 0, extrasData.length);
-                parcel.setDataPosition(0);
-                extras = parcel.readBundle();
-            } catch (RuntimeException e) {
-                // A RuntimeException is thrown if we were unable to parse the parcel.
-                // Create an empty parcel in this case.
-                extras = new Bundle();
-            } finally {
-                parcel.recycle();
-            }
-
-            SyncOperation syncOperation = new SyncOperation(
-                    cursor.getString(COLUMN_ACCOUNT),
-                    cursor.getInt(COLUMN_SOURCE),
-                    cursor.getString(COLUMN_AUTHORITY),
-                    extras,
-                    0 /* delay */);
-            syncOperation.rowId = cursor.getLong(COLUMN_ID);
-            return syncOperation;
-        }
     }
 }
diff --git a/core/java/android/content/SyncProvider.java b/core/java/android/content/SyncProvider.java
deleted file mode 100644
index 6ddd046..0000000
--- a/core/java/android/content/SyncProvider.java
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2007 The Android Open Source Project
-package android.content;
-
-import android.database.Cursor;
-import android.net.Uri;
-
-/**
- * ContentProvider that tracks the sync data and overall sync
- * history on the device.
- * 
- * @hide
- */
-public class SyncProvider extends ContentProvider {
-    public SyncProvider() {
-    }
-
-    private SyncStorageEngine mSyncStorageEngine;
-
-    @Override
-    public boolean onCreate() {
-        mSyncStorageEngine = SyncStorageEngine.getSingleton();
-        return true;
-    }
-
-    @Override
-    public Cursor query(Uri url, String[] projectionIn,
-                        String selection, String[] selectionArgs, String sort) {
-        return mSyncStorageEngine.query(url, projectionIn, selection, selectionArgs, sort);
-    }
-
-    @Override
-    public Uri insert(Uri url, ContentValues initialValues) {
-        return mSyncStorageEngine.insert(true /* the caller is the provider */,
-                url, initialValues);
-    }
-
-    @Override
-    public int delete(Uri url, String where, String[] whereArgs) {
-        return mSyncStorageEngine.delete(true /* the caller is the provider */,
-                url, where, whereArgs);
-    }
-
-    @Override
-    public int update(Uri url, ContentValues initialValues, String where, String[] whereArgs) {
-        return mSyncStorageEngine.update(true /* the caller is the provider */, 
-                url, initialValues, where, whereArgs);
-    }
-
-    @Override
-    public String getType(Uri url) {
-        return mSyncStorageEngine.getType(url);
-    }
-}
diff --git a/core/java/android/content/SyncStatusInfo.aidl b/core/java/android/content/SyncStatusInfo.aidl
new file mode 100644
index 0000000..b188c0b
--- /dev/null
+++ b/core/java/android/content/SyncStatusInfo.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+parcelable SyncStatusInfo;
diff --git a/core/java/android/content/SyncStatusInfo.java b/core/java/android/content/SyncStatusInfo.java
new file mode 100644
index 0000000..6687fcb
--- /dev/null
+++ b/core/java/android/content/SyncStatusInfo.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.content;
+
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.Log;
+
+/** @hide */
+public class SyncStatusInfo implements Parcelable {
+    static final int VERSION = 1;
+    
+    public final int authorityId;
+    public long totalElapsedTime;
+    public int numSyncs;
+    public int numSourcePoll;
+    public int numSourceServer;
+    public int numSourceLocal;
+    public int numSourceUser;
+    public long lastSuccessTime;
+    public int lastSuccessSource;
+    public long lastFailureTime;
+    public int lastFailureSource;
+    public String lastFailureMesg;
+    public long initialFailureTime;
+    public boolean pending;
+    
+    SyncStatusInfo(int authorityId) {
+        this.authorityId = authorityId;
+    }
+
+    public int getLastFailureMesgAsInt(int def) {
+        try {
+            if (lastFailureMesg != null) {
+                return Integer.parseInt(lastFailureMesg);
+            }
+        } catch (NumberFormatException e) {
+        }
+        return def;
+    }
+    
+    public int describeContents() {
+        return 0;
+    }
+
+    public void writeToParcel(Parcel parcel, int flags) {
+        parcel.writeInt(VERSION);
+        parcel.writeInt(authorityId);
+        parcel.writeLong(totalElapsedTime);
+        parcel.writeInt(numSyncs);
+        parcel.writeInt(numSourcePoll);
+        parcel.writeInt(numSourceServer);
+        parcel.writeInt(numSourceLocal);
+        parcel.writeInt(numSourceUser);
+        parcel.writeLong(lastSuccessTime);
+        parcel.writeInt(lastSuccessSource);
+        parcel.writeLong(lastFailureTime);
+        parcel.writeInt(lastFailureSource);
+        parcel.writeString(lastFailureMesg);
+        parcel.writeLong(initialFailureTime);
+        parcel.writeInt(pending ? 1 : 0);
+    }
+
+    SyncStatusInfo(Parcel parcel) {
+        int version = parcel.readInt();
+        if (version != VERSION) {
+            Log.w("SyncStatusInfo", "Unknown version: " + version);
+        }
+        authorityId = parcel.readInt();
+        totalElapsedTime = parcel.readLong();
+        numSyncs = parcel.readInt();
+        numSourcePoll = parcel.readInt();
+        numSourceServer = parcel.readInt();
+        numSourceLocal = parcel.readInt();
+        numSourceUser = parcel.readInt();
+        lastSuccessTime = parcel.readLong();
+        lastSuccessSource = parcel.readInt();
+        lastFailureTime = parcel.readLong();
+        lastFailureSource = parcel.readInt();
+        lastFailureMesg = parcel.readString();
+        initialFailureTime = parcel.readLong();
+        pending = parcel.readInt() != 0;
+    }
+    
+    public static final Creator<SyncStatusInfo> CREATOR = new Creator<SyncStatusInfo>() {
+        public SyncStatusInfo createFromParcel(Parcel in) {
+            return new SyncStatusInfo(in);
+        }
+
+        public SyncStatusInfo[] newArray(int size) {
+            return new SyncStatusInfo[size];
+        }
+    };
+}
\ No newline at end of file
diff --git a/core/java/android/content/SyncStorageEngine.java b/core/java/android/content/SyncStorageEngine.java
index 282f6e7..1587462 100644
--- a/core/java/android/content/SyncStorageEngine.java
+++ b/core/java/android/content/SyncStorageEngine.java
@@ -1,125 +1,282 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
 package android.content;
 
-import android.Manifest;
-import android.database.Cursor;
-import android.database.DatabaseUtils;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
-import android.net.Uri;
-import android.provider.Sync;
-import android.text.TextUtils;
-import android.util.Config;
-import android.util.Log;
+import com.android.internal.os.AtomicFile;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.FastXmlSerializer;
 
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+import org.xmlpull.v1.XmlSerializer;
+
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.Message;
+import android.os.Parcel;
+import android.os.RemoteCallbackList;
+import android.os.RemoteException;
+import android.util.Log;
+import android.util.SparseArray;
+import android.util.Xml;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
 import java.util.ArrayList;
+import java.util.Calendar;
 import java.util.HashMap;
-import java.util.HashSet;
+import java.util.Iterator;
+import java.util.TimeZone;
 
 /**
- * ContentProvider that tracks the sync data and overall sync
+ * Singleton that tracks the sync data and overall sync
  * history on the device.
  * 
  * @hide
  */
-public class SyncStorageEngine {
+public class SyncStorageEngine extends Handler {
     private static final String TAG = "SyncManager";
+    private static final boolean DEBUG = false;
+    private static final boolean DEBUG_FILE = false;
+    
+    // @VisibleForTesting
+    static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4;
 
-    private static final String DATABASE_NAME = "syncmanager.db";
-    private static final int DATABASE_VERSION = 10;
+    /** Enum value for a sync start event. */
+    public static final int EVENT_START = 0;
 
-    private static final int STATS = 1;
-    private static final int STATS_ID = 2;
-    private static final int HISTORY = 3;
-    private static final int HISTORY_ID = 4;
-    private static final int SETTINGS = 5;
-    private static final int PENDING = 7;
-    private static final int ACTIVE = 8;
-    private static final int STATUS = 9;
+    /** Enum value for a sync stop event. */
+    public static final int EVENT_STOP = 1;
 
-    private static final UriMatcher sURLMatcher =
-            new UriMatcher(UriMatcher.NO_MATCH);
+    // TODO: i18n -- grab these out of resources.
+    /** String names for the sync event types. */
+    public static final String[] EVENTS = { "START", "STOP" };
 
-    private static final HashMap<String,String> HISTORY_PROJECTION_MAP;
-    private static final HashMap<String,String> PENDING_PROJECTION_MAP;
-    private static final HashMap<String,String> ACTIVE_PROJECTION_MAP;
-    private static final HashMap<String,String> STATUS_PROJECTION_MAP;
+    /** Enum value for a server-initiated sync. */
+    public static final int SOURCE_SERVER = 0;
 
-    private final Context mContext;
-    private final SQLiteOpenHelper mOpenHelper;
-    private static SyncStorageEngine sSyncStorageEngine = null;
+    /** Enum value for a local-initiated sync. */
+    public static final int SOURCE_LOCAL = 1;
+    /**
+     * Enum value for a poll-based sync (e.g., upon connection to
+     * network)
+     */
+    public static final int SOURCE_POLL = 2;
 
-    static {
-        sURLMatcher.addURI("sync", "stats", STATS);
-        sURLMatcher.addURI("sync", "stats/#", STATS_ID);
-        sURLMatcher.addURI("sync", "history", HISTORY);
-        sURLMatcher.addURI("sync", "history/#", HISTORY_ID);
-        sURLMatcher.addURI("sync", "settings", SETTINGS);
-        sURLMatcher.addURI("sync", "status", STATUS);
-        sURLMatcher.addURI("sync", "active", ACTIVE);
-        sURLMatcher.addURI("sync", "pending", PENDING);
+    /** Enum value for a user-initiated sync. */
+    public static final int SOURCE_USER = 3;
 
-        HashMap<String,String> map;
-        PENDING_PROJECTION_MAP = map = new HashMap<String,String>();
-        map.put(Sync.History._ID, Sync.History._ID);
-        map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
-        map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);
+    // TODO: i18n -- grab these out of resources.
+    /** String names for the sync source types. */
+    public static final String[] SOURCES = { "SERVER",
+                                             "LOCAL",
+                                             "POLL",
+                                             "USER" };
 
-        ACTIVE_PROJECTION_MAP = map = new HashMap<String,String>();
-        map.put(Sync.History._ID, Sync.History._ID);
-        map.put(Sync.History.ACCOUNT, Sync.History.ACCOUNT);
-        map.put(Sync.History.AUTHORITY, Sync.History.AUTHORITY);
-        map.put("startTime", "startTime");
+    // Error types
+    public static final int ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
+    public static final int ERROR_AUTHENTICATION = 2;
+    public static final int ERROR_IO = 3;
+    public static final int ERROR_PARSE = 4;
+    public static final int ERROR_CONFLICT = 5;
+    public static final int ERROR_TOO_MANY_DELETIONS = 6;
+    public static final int ERROR_TOO_MANY_RETRIES = 7;
+    public static final int ERROR_INTERNAL = 8;
 
-        HISTORY_PROJECTION_MAP = map = new HashMap<String,String>();
-        map.put(Sync.History._ID, "history._id as _id");
-        map.put(Sync.History.ACCOUNT, "stats.account as account");
-        map.put(Sync.History.AUTHORITY, "stats.authority as authority");
-        map.put(Sync.History.EVENT, Sync.History.EVENT);
-        map.put(Sync.History.EVENT_TIME, Sync.History.EVENT_TIME);
-        map.put(Sync.History.ELAPSED_TIME, Sync.History.ELAPSED_TIME);
-        map.put(Sync.History.SOURCE, Sync.History.SOURCE);
-        map.put(Sync.History.UPSTREAM_ACTIVITY, Sync.History.UPSTREAM_ACTIVITY);
-        map.put(Sync.History.DOWNSTREAM_ACTIVITY, Sync.History.DOWNSTREAM_ACTIVITY);
-        map.put(Sync.History.MESG, Sync.History.MESG);
+    // The MESG column will contain one of these or one of the Error types.
+    public static final String MESG_SUCCESS = "success";
+    public static final String MESG_CANCELED = "canceled";
 
-        STATUS_PROJECTION_MAP = map = new HashMap<String,String>();
-        map.put(Sync.Status._ID, "status._id as _id");
-        map.put(Sync.Status.ACCOUNT, "stats.account as account");
-        map.put(Sync.Status.AUTHORITY, "stats.authority as authority");
-        map.put(Sync.Status.TOTAL_ELAPSED_TIME, Sync.Status.TOTAL_ELAPSED_TIME);
-        map.put(Sync.Status.NUM_SYNCS, Sync.Status.NUM_SYNCS);
-        map.put(Sync.Status.NUM_SOURCE_LOCAL, Sync.Status.NUM_SOURCE_LOCAL);
-        map.put(Sync.Status.NUM_SOURCE_POLL, Sync.Status.NUM_SOURCE_POLL);
-        map.put(Sync.Status.NUM_SOURCE_SERVER, Sync.Status.NUM_SOURCE_SERVER);
-        map.put(Sync.Status.NUM_SOURCE_USER, Sync.Status.NUM_SOURCE_USER);
-        map.put(Sync.Status.LAST_SUCCESS_SOURCE, Sync.Status.LAST_SUCCESS_SOURCE);
-        map.put(Sync.Status.LAST_SUCCESS_TIME, Sync.Status.LAST_SUCCESS_TIME);
-        map.put(Sync.Status.LAST_FAILURE_SOURCE, Sync.Status.LAST_FAILURE_SOURCE);
-        map.put(Sync.Status.LAST_FAILURE_TIME, Sync.Status.LAST_FAILURE_TIME);
-        map.put(Sync.Status.LAST_FAILURE_MESG, Sync.Status.LAST_FAILURE_MESG);
-        map.put(Sync.Status.PENDING, Sync.Status.PENDING);
+    public static final int CHANGE_SETTINGS = 1<<0;
+    public static final int CHANGE_PENDING = 1<<1;
+    public static final int CHANGE_ACTIVE = 1<<2;
+    public static final int CHANGE_STATUS = 1<<3;
+    public static final int CHANGE_ALL = 0x7fffffff;
+    
+    public static final int MAX_HISTORY = 15;
+    
+    private static final int MSG_WRITE_STATUS = 1;
+    private static final long WRITE_STATUS_DELAY = 1000*60*10; // 10 minutes
+    
+    private static final int MSG_WRITE_STATISTICS = 2;
+    private static final long WRITE_STATISTICS_DELAY = 1000*60*30; // 1/2 hour
+    
+    public static class PendingOperation {
+        final String account;
+        final int syncSource;
+        final String authority;
+        final Bundle extras;        // note: read-only.
+        
+        int authorityId;
+        byte[] flatExtras;
+        
+        PendingOperation(String account, int source,
+                String authority, Bundle extras) {
+            this.account = account;
+            this.syncSource = source;
+            this.authority = authority;
+            this.extras = extras != null ? new Bundle(extras) : extras;
+            this.authorityId = -1;
+        }
+
+        PendingOperation(PendingOperation other) {
+            this.account = other.account;
+            this.syncSource = other.syncSource;
+            this.authority = other.authority;
+            this.extras = other.extras;
+            this.authorityId = other.authorityId;
+        }
     }
+    
+    static class AccountInfo {
+        final String account;
+        final HashMap<String, AuthorityInfo> authorities =
+                new HashMap<String, AuthorityInfo>();
+        
+        AccountInfo(String account) {
+            this.account = account;
+        }
+    }
+    
+    public static class AuthorityInfo {
+        final String account;
+        final String authority;
+        final int ident;
+        boolean enabled;
+        
+        AuthorityInfo(String account, String authority, int ident) {
+            this.account = account;
+            this.authority = authority;
+            this.ident = ident;
+            enabled = true;
+        }
+    }
+    
+    public static class SyncHistoryItem {
+        int authorityId;
+        int historyId;
+        long eventTime;
+        long elapsedTime;
+        int source;
+        int event;
+        long upstreamActivity;
+        long downstreamActivity;
+        String mesg;
+    }
+    
+    public static class DayStats {
+        public final int day;
+        public int successCount;
+        public long successTime;
+        public int failureCount;
+        public long failureTime;
+        
+        public DayStats(int day) {
+            this.day = day;
+        }
+    }
+    
+    // Primary list of all syncable authorities.  Also our global lock.
+    private final SparseArray<AuthorityInfo> mAuthorities =
+            new SparseArray<AuthorityInfo>();
+    
+    private final HashMap<String, AccountInfo> mAccounts =
+        new HashMap<String, AccountInfo>();
 
-    private static final String[] STATS_ACCOUNT_PROJECTION =
-            new String[] { Sync.Stats.ACCOUNT };
-
-    private static final int MAX_HISTORY_EVENTS_TO_KEEP = 5000;
-
-    private static final String SELECT_INITIAL_FAILURE_TIME_QUERY_STRING = ""
-            + "SELECT min(a) "
-            + "FROM ("
-            + "  SELECT initialFailureTime AS a "
-            + "  FROM status "
-            + "  WHERE stats_id=? AND a IS NOT NULL "
-            + "    UNION "
-            + "  SELECT ? AS a"
-            + " )";
-
+    private final ArrayList<PendingOperation> mPendingOperations =
+            new ArrayList<PendingOperation>();
+    
+    private ActiveSyncInfo mActiveSync;
+    
+    private final SparseArray<SyncStatusInfo> mSyncStatus =
+            new SparseArray<SyncStatusInfo>();
+    
+    private final ArrayList<SyncHistoryItem> mSyncHistory =
+            new ArrayList<SyncHistoryItem>();
+    
+    private final RemoteCallbackList<ISyncStatusObserver> mChangeListeners
+            = new RemoteCallbackList<ISyncStatusObserver>();
+    
+    // We keep 4 weeks of stats.
+    private final DayStats[] mDayStats = new DayStats[7*4];
+    private final Calendar mCal;
+    private int mYear;
+    private int mYearInDays;
+    
+    private final Context mContext;
+    private static volatile SyncStorageEngine sSyncStorageEngine = null;
+    
+    /**
+     * This file contains the core engine state: all accounts and the
+     * settings for them.  It must never be lost, and should be changed
+     * infrequently, so it is stored as an XML file.
+     */
+    private final AtomicFile mAccountInfoFile;
+    
+    /**
+     * This file contains the current sync status.  We would like to retain
+     * it across boots, but its loss is not the end of the world, so we store
+     * this information as binary data.
+     */
+    private final AtomicFile mStatusFile;
+    
+    /**
+     * This file contains sync statistics.  This is purely debugging information
+     * so is written infrequently and can be thrown away at any time.
+     */
+    private final AtomicFile mStatisticsFile;
+    
+    /**
+     * This file contains the pending sync operations.  It is a binary file,
+     * which must be updated every time an operation is added or removed,
+     * so we have special handling of it.
+     */
+    private final AtomicFile mPendingFile;
+    private static final int PENDING_FINISH_TO_WRITE = 4;
+    private int mNumPendingFinished = 0;
+    
+    private int mNextHistoryId = 0;
+    private boolean mListenForTickles = true;
+    
     private SyncStorageEngine(Context context) {
         mContext = context;
-        mOpenHelper = new SyncStorageEngine.DatabaseHelper(context);
         sSyncStorageEngine = this;
+        
+        mCal = Calendar.getInstance(TimeZone.getTimeZone("GMT+0"));
+        
+        File dataDir = Environment.getDataDirectory();
+        File systemDir = new File(dataDir, "system");
+        File syncDir = new File(systemDir, "sync");
+        mAccountInfoFile = new AtomicFile(new File(syncDir, "accounts.xml"));
+        mStatusFile = new AtomicFile(new File(syncDir, "status.bin"));
+        mPendingFile = new AtomicFile(new File(syncDir, "pending.bin"));
+        mStatisticsFile = new AtomicFile(new File(syncDir, "stats.bin"));
+        
+        readAccountInfoLocked();
+        readStatusLocked();
+        readPendingOperationsLocked();
+        readStatisticsLocked();
+        readLegacyAccountInfoLocked();
     }
 
     public static SyncStorageEngine newTestInstance(Context context) {
@@ -140,619 +297,1249 @@
         return sSyncStorageEngine;
     }
 
-    private class DatabaseHelper extends SQLiteOpenHelper {
-        DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE pending ("
-                    + "_id INTEGER PRIMARY KEY,"
-                    + "authority TEXT NOT NULL,"
-                    + "account TEXT NOT NULL,"
-                    + "extras BLOB NOT NULL,"
-                    + "source INTEGER NOT NULL"
-                    + ");");
-
-            db.execSQL("CREATE TABLE stats (" +
-                       "_id INTEGER PRIMARY KEY," +
-                       "account TEXT, " +
-                       "authority TEXT, " +
-                       "syncdata TEXT, " +
-                       "UNIQUE (account, authority)" +
-                       ");");
-
-            db.execSQL("CREATE TABLE history (" +
-                       "_id INTEGER PRIMARY KEY," +
-                       "stats_id INTEGER," +
-                       "eventTime INTEGER," +
-                       "elapsedTime INTEGER," +
-                       "source INTEGER," +
-                       "event INTEGER," +
-                       "upstreamActivity INTEGER," +
-                       "downstreamActivity INTEGER," +
-                       "mesg TEXT);");
-
-            db.execSQL("CREATE TABLE status ("
-                    + "_id INTEGER PRIMARY KEY,"
-                    + "stats_id INTEGER NOT NULL,"
-                    + "totalElapsedTime INTEGER NOT NULL DEFAULT 0,"
-                    + "numSyncs INTEGER NOT NULL DEFAULT 0,"
-                    + "numSourcePoll INTEGER NOT NULL DEFAULT 0,"
-                    + "numSourceServer INTEGER NOT NULL DEFAULT 0,"
-                    + "numSourceLocal INTEGER NOT NULL DEFAULT 0,"
-                    + "numSourceUser INTEGER NOT NULL DEFAULT 0,"
-                    + "lastSuccessTime INTEGER,"
-                    + "lastSuccessSource INTEGER,"
-                    + "lastFailureTime INTEGER,"
-                    + "lastFailureSource INTEGER,"
-                    + "lastFailureMesg STRING,"
-                    + "initialFailureTime INTEGER,"
-                    + "pending INTEGER NOT NULL DEFAULT 0);");
-
-            db.execSQL("CREATE TABLE active ("
-                    + "_id INTEGER PRIMARY KEY,"
-                    + "authority TEXT,"
-                    + "account TEXT,"
-                    + "startTime INTEGER);");
-
-            db.execSQL("CREATE INDEX historyEventTime ON history (eventTime)");
-
-            db.execSQL("CREATE TABLE settings (" +
-                       "name TEXT PRIMARY KEY," +
-                       "value TEXT);");
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-            if (oldVersion == 9 && newVersion == 10) {
-                Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
-                        + newVersion + ", which will preserve old data");
-                db.execSQL("ALTER TABLE status ADD COLUMN initialFailureTime INTEGER");
-                return;
+    @Override public void handleMessage(Message msg) {
+        if (msg.what == MSG_WRITE_STATUS) {
+            synchronized (mAccounts) {
+                writeStatusLocked();
             }
-
-            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
-                    + newVersion + ", which will destroy all old data");
-            db.execSQL("DROP TABLE IF EXISTS pending");
-            db.execSQL("DROP TABLE IF EXISTS stats");
-            db.execSQL("DROP TABLE IF EXISTS history");
-            db.execSQL("DROP TABLE IF EXISTS settings");
-            db.execSQL("DROP TABLE IF EXISTS active");
-            db.execSQL("DROP TABLE IF EXISTS status");
-            onCreate(db);
-        }
-
-        @Override
-        public void onOpen(SQLiteDatabase db) {
-            if (!db.isReadOnly()) {
-                db.delete("active", null, null);
-                db.insert("active", "account", null);
+        } else if (msg.what == MSG_WRITE_STATISTICS) {
+            synchronized (mAccounts) {
+                writeStatisticsLocked();
             }
         }
     }
-
-    protected void doDatabaseCleanup(String[] accounts) {
-        HashSet<String> currentAccounts = new HashSet<String>();
-        for (String account : accounts) currentAccounts.add(account);
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        Cursor cursor = db.query("stats", STATS_ACCOUNT_PROJECTION,
-                null /* where */, null /* where args */, Sync.Stats.ACCOUNT,
-                null /* having */, null /* order by */);
-        try {
-            while (cursor.moveToNext()) {
-                String account = cursor.getString(0);
-                if (TextUtils.isEmpty(account)) {
+    
+    public void addStatusChangeListener(int mask, ISyncStatusObserver callback) {
+        synchronized (mAuthorities) {
+            mChangeListeners.register(callback, mask);
+        }
+    }
+    
+    public void removeStatusChangeListener(ISyncStatusObserver callback) {
+        synchronized (mAuthorities) {
+            mChangeListeners.unregister(callback);
+        }
+    }
+    
+    private void reportChange(int which) {
+        ArrayList<ISyncStatusObserver> reports = null;
+        synchronized (mAuthorities) {
+            int i = mChangeListeners.beginBroadcast();
+            while (i > 0) {
+                i--;
+                Integer mask = (Integer)mChangeListeners.getBroadcastCookie(i);
+                if ((which & mask.intValue()) == 0) {
                     continue;
                 }
-                if (!currentAccounts.contains(account)) {
-                    String where = Sync.Stats.ACCOUNT + "=?";
-                    int numDeleted;
-                    numDeleted = db.delete("stats", where, new String[]{account});
-                    if (Config.LOGD) {
-                        Log.d(TAG, "deleted " + numDeleted
-                                + " records from stats table"
-                                + " for account " + account);
+                if (reports == null) {
+                    reports = new ArrayList<ISyncStatusObserver>(i);
+                }
+                reports.add(mChangeListeners.getBroadcastItem(i));
+            }
+        }
+        
+        if (DEBUG) Log.v(TAG, "reportChange " + which + " to: " + reports);
+        
+        if (reports != null) {
+            int i = reports.size();
+            while (i > 0) {
+                i--;
+                try {
+                    reports.get(i).onStatusChanged(which);
+                } catch (RemoteException e) {
+                    // The remote callback list will take care of this for us.
+                }
+            }
+        }
+    }
+    
+    public boolean getSyncProviderAutomatically(String account, String providerName) {
+        synchronized (mAuthorities) {
+            if (account != null) {
+                AuthorityInfo authority = getAuthorityLocked(account, providerName,
+                        "getSyncProviderAutomatically");
+                return authority != null ? authority.enabled : false;
+            }
+            
+            int i = mAuthorities.size();
+            while (i > 0) {
+                i--;
+                AuthorityInfo authority = mAuthorities.get(i);
+                if (authority.authority.equals(providerName)
+                        && authority.enabled) {
+                    return true;
+                }
+            }
+            return false;
+        }
+    }
+
+    public void setSyncProviderAutomatically(String account, String providerName, boolean sync) {
+        synchronized (mAuthorities) {
+            if (account != null) {
+                AuthorityInfo authority = getAuthorityLocked(account, providerName,
+                        "setSyncProviderAutomatically");
+                if (authority != null) {
+                    authority.enabled = sync;
+                }
+            } else {
+                int i = mAuthorities.size();
+                while (i > 0) {
+                    i--;
+                    AuthorityInfo authority = mAuthorities.get(i);
+                    if (authority.account.equals(account)
+                            && authority.authority.equals(providerName)) {
+                        authority.enabled = sync;
                     }
                 }
             }
-        } finally {
-            cursor.close();
+            writeAccountInfoLocked();
         }
-    }
-
-    protected void setActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
-        if (activeSyncContext != null) {
-            updateActiveSync(activeSyncContext.mSyncOperation.account,
-                    activeSyncContext.mSyncOperation.authority, activeSyncContext.mStartTime);
-        } else {
-            // we indicate that the sync is not active by passing null for all the parameters
-            updateActiveSync(null, null, null);
-        }
-    }
-
-    private int updateActiveSync(String account, String authority, Long startTime) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        ContentValues values = new ContentValues();
-        values.put("account", account);
-        values.put("authority", authority);
-        values.put("startTime", startTime);
-        int numChanges = db.update("active", values, null, null);
-        if (numChanges > 0) {
-            mContext.getContentResolver().notifyChange(Sync.Active.CONTENT_URI,
-                    null /* this change wasn't made through an observer */);
-        }
-        return numChanges;
-    }
-
-    /**
-     * Implements the {@link ContentProvider#query} method
-     */
-    public Cursor query(Uri url, String[] projectionIn,
-            String selection, String[] selectionArgs, String sort) {
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-
-        // Generate the body of the query
-        int match = sURLMatcher.match(url);
-        String groupBy = null;
-        switch (match) {
-            case STATS:
-                qb.setTables("stats");
-                break;
-            case STATS_ID:
-                qb.setTables("stats");
-                qb.appendWhere("_id=");
-                qb.appendWhere(url.getPathSegments().get(1));
-                break;
-            case HISTORY:
-                // join the stats and history tables, so the caller can get
-                // the account and authority information as part of this query.
-                qb.setTables("stats, history");
-                qb.setProjectionMap(HISTORY_PROJECTION_MAP);
-                qb.appendWhere("stats._id = history.stats_id");
-                break;
-            case ACTIVE:
-                qb.setTables("active");
-                qb.setProjectionMap(ACTIVE_PROJECTION_MAP);
-                qb.appendWhere("account is not null");
-                break;
-            case PENDING:
-                qb.setTables("pending");
-                qb.setProjectionMap(PENDING_PROJECTION_MAP);
-                groupBy = "account, authority";
-                break;
-            case STATUS:
-                // join the stats and status tables, so the caller can get
-                // the account and authority information as part of this query.
-                qb.setTables("stats, status");
-                qb.setProjectionMap(STATUS_PROJECTION_MAP);
-                qb.appendWhere("stats._id = status.stats_id");
-                break;
-            case HISTORY_ID:
-                // join the stats and history tables, so the caller can get
-                // the account and authority information as part of this query.
-                qb.setTables("stats, history");
-                qb.setProjectionMap(HISTORY_PROJECTION_MAP);
-                qb.appendWhere("stats._id = history.stats_id");
-                qb.appendWhere("AND history._id=");
-                qb.appendWhere(url.getPathSegments().get(1));
-                break;
-            case SETTINGS:
-                qb.setTables("settings");
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown URL " + url);
-        }
-
-        if (match == SETTINGS) {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_SETTINGS,
-                    "no permission to read the sync settings");
-        } else {
-            mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
-                    "no permission to read the sync stats");
-        }
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        Cursor c = qb.query(db, projectionIn, selection, selectionArgs, groupBy, null, sort);
-        c.setNotificationUri(mContext.getContentResolver(), url);
-        return c;
-    }
-
-    /**
-     * Implements the {@link ContentProvider#insert} method
-     * @param callerIsTheProvider true if this is being called via the
-     *  {@link ContentProvider#insert} in method rather than directly.
-     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
-     *   for the Settings table.
-     */
-    public Uri insert(boolean callerIsTheProvider, Uri url, ContentValues values) {
-        String table;
-        long rowID;
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        final int match = sURLMatcher.match(url);
-        checkCaller(callerIsTheProvider, match);
-        switch (match) {
-            case SETTINGS:
-                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
-                        "no permission to write the sync settings");
-                table = "settings";
-                rowID = db.replace(table, null, values);
-                break;
-            default:
-                throw new IllegalArgumentException("Unknown URL " + url);
-        }
-
-
-        if (rowID > 0) {
-            mContext.getContentResolver().notifyChange(url, null /* observer */);
-            return Uri.parse("content://sync/" + table + "/" + rowID);
-        }
-
-        return null;
-    }
-
-    private static void checkCaller(boolean callerIsTheProvider, int match) {
-        if (callerIsTheProvider && match != SETTINGS) {
-            throw new UnsupportedOperationException(
-                    "only the settings are modifiable via the ContentProvider interface");
-        }
-    }
-
-    /**
-     * Implements the {@link ContentProvider#delete} method
-     * @param callerIsTheProvider true if this is being called via the
-     *  {@link ContentProvider#delete} in method rather than directly.
-     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
-     *   for the Settings table.
-     */
-    public int delete(boolean callerIsTheProvider, Uri url, String where, String[] whereArgs) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        int match = sURLMatcher.match(url);
-
-        int numRows;
-        switch (match) {
-            case SETTINGS:
-                mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SYNC_SETTINGS,
-                        "no permission to write the sync settings");
-                numRows = db.delete("settings", where, whereArgs);
-                break;
-            default:
-                throw new UnsupportedOperationException("Cannot delete URL: " + url);
-        }
-
-        if (numRows > 0) {
-            mContext.getContentResolver().notifyChange(url, null /* observer */);
-        }
-        return numRows;
-    }
-
-    /**
-     * Implements the {@link ContentProvider#update} method
-     * @param callerIsTheProvider true if this is being called via the
-     *  {@link ContentProvider#update} in method rather than directly.
-     * @throws UnsupportedOperationException if callerIsTheProvider is true and the url isn't
-     *   for the Settings table.
-     */
-    public int update(boolean callerIsTheProvider, Uri url, ContentValues initialValues,
-            String where, String[] whereArgs) {
-        switch (sURLMatcher.match(url)) {
-            case SETTINGS:
-                throw new UnsupportedOperationException("updating url " + url
-                        + " is not allowed, use insert instead");
-            default:
-                throw new UnsupportedOperationException("Cannot update URL: " + url);
-        }
-    }
-
-    /**
-     * Implements the {@link ContentProvider#getType} method
-     */
-    public String getType(Uri url) {
-        int match = sURLMatcher.match(url);
-        switch (match) {
-            case SETTINGS:
-                return "vnd.android.cursor.dir/sync-settings";
-            default:
-                throw new IllegalArgumentException("Unknown URL");
-        }
-    }
-
-    protected Uri insertIntoPending(ContentValues values) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        try {
-            db.beginTransaction();
-            long rowId = db.insert("pending", Sync.Pending.ACCOUNT, values);
-            if (rowId < 0) return null;
-            String account = values.getAsString(Sync.Pending.ACCOUNT);
-            String authority = values.getAsString(Sync.Pending.AUTHORITY);
-
-            long statsId = createStatsRowIfNecessary(account, authority);
-            createStatusRowIfNecessary(statsId);
-
-            values.clear();
-            values.put(Sync.Status.PENDING, 1);
-            int numUpdatesStatus = db.update("status", values, "stats_id=" + statsId, null);
-
-            db.setTransactionSuccessful();
-
-            mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
-                    null /* no observer initiated this change */);
-            if (numUpdatesStatus > 0) {
-                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
-                        null /* no observer initiated this change */);
-            }
-            return ContentUris.withAppendedId(Sync.Pending.CONTENT_URI, rowId);
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    int deleteFromPending(long rowId) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
-            String account;
-            String authority;
-            Cursor c = db.query("pending",
-                    new String[]{Sync.Pending.ACCOUNT, Sync.Pending.AUTHORITY},
-                    "_id=" + rowId, null, null, null, null);
-            try {
-                if (c.getCount() != 1) {
-                    return 0;
-                }
-                c.moveToNext();
-                account = c.getString(0);
-                authority = c.getString(1);
-            } finally {
-                c.close();
-            }
-            db.delete("pending", "_id=" + rowId, null /* no where args */);
-            final String[] accountAuthorityWhereArgs = new String[]{account, authority};
-            boolean isPending = 0 < DatabaseUtils.longForQuery(db,
-                    "SELECT COUNT(*) FROM PENDING WHERE account=? AND authority=?",
-                    accountAuthorityWhereArgs);
-            if (!isPending) {
-                long statsId = createStatsRowIfNecessary(account, authority);
-                db.execSQL("UPDATE status SET pending=0 WHERE stats_id=" + statsId);
-            }
-            db.setTransactionSuccessful();
-
-            mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
-                    null /* no observer initiated this change */);
-            if (!isPending) {
-                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
-                        null /* no observer initiated this change */);
-            }
-            return 1;
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    int clearPending() {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
-            int numChanges = db.delete("pending", null, null /* no where args */);
-            if (numChanges > 0) {
-                db.execSQL("UPDATE status SET pending=0");
-                mContext.getContentResolver().notifyChange(Sync.Pending.CONTENT_URI,
-                        null /* no observer initiated this change */);
-                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
-                        null /* no observer initiated this change */);
-            }
-            db.setTransactionSuccessful();
-            return numChanges;
-        } finally {
-            db.endTransaction();
-        }
-    }
-
-    /**
-     * Returns a cursor over all the pending syncs in no particular order. This cursor is not
-     * "live", in that if changes are made to the pending table any observers on this cursor
-     * will not be notified.
-     * @param projection Return only these columns. If null then all columns are returned.
-     * @return the cursor of pending syncs
-     */
-    public Cursor getPendingSyncsCursor(String[] projection) {
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        return db.query("pending", projection, null, null, null, null, null);
-    }
-
-    // @VisibleForTesting
-    static final long MILLIS_IN_4WEEKS = 1000L * 60 * 60 * 24 * 7 * 4;
-
-    private boolean purgeOldHistoryEvents(long now) {
-        // remove events that are older than MILLIS_IN_4WEEKS
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        int numDeletes = db.delete("history", "eventTime<" + (now - MILLIS_IN_4WEEKS), null);
-        if (Log.isLoggable(TAG, Log.VERBOSE)) {
-            if (numDeletes > 0) {
-                Log.v(TAG, "deleted " + numDeletes + " old event(s) from the sync history");
-            }
-        }
-
-        // keep only the last MAX_HISTORY_EVENTS_TO_KEEP history events
-        numDeletes += db.delete("history", "eventTime < (select min(eventTime) from "
-                + "(select eventTime from history order by eventTime desc limit ?))",
-                new String[]{String.valueOf(MAX_HISTORY_EVENTS_TO_KEEP)});
         
-        return numDeletes > 0;
+        reportChange(CHANGE_SETTINGS);
     }
 
-    public long insertStartSyncEvent(String account, String authority, long now, int source) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        long statsId = createStatsRowIfNecessary(account, authority);
+    public void setListenForNetworkTickles(boolean flag) {
+        synchronized (mAuthorities) {
+            mListenForTickles = flag;
+            writeAccountInfoLocked();
+        }
+        reportChange(CHANGE_SETTINGS);
+    }
 
-        purgeOldHistoryEvents(now);
-        ContentValues values = new ContentValues();
-        values.put(Sync.History.STATS_ID, statsId);
-        values.put(Sync.History.EVENT_TIME, now);
-        values.put(Sync.History.SOURCE, source);
-        values.put(Sync.History.EVENT, Sync.History.EVENT_START);
-        long rowId = db.insert("history", null, values);
-        mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI, null /* observer */);
-        mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI, null /* observer */);
-        return rowId;
+    public boolean getListenForNetworkTickles() {
+        synchronized (mAuthorities) {
+            return mListenForTickles;
+        }
+    }
+    
+    public AuthorityInfo getAuthority(String account, String authority) {
+        synchronized (mAuthorities) {
+            return getAuthorityLocked(account, authority, null);
+        }
+    }
+    
+    public AuthorityInfo getAuthority(int authorityId) {
+        synchronized (mAuthorities) {
+            return mAuthorities.get(authorityId);
+        }
+    }
+    
+    /**
+     * Returns true if there is currently a sync operation for the given
+     * account or authority in the pending list, or actively being processed.
+     */
+    public boolean isSyncActive(String account, String authority) {
+        synchronized (mAuthorities) {
+            int i = mPendingOperations.size();
+            while (i > 0) {
+                i--;
+                // TODO(fredq): this probably shouldn't be considering
+                // pending operations.
+                PendingOperation op = mPendingOperations.get(i);
+                if (op.account.equals(account) && op.authority.equals(authority)) {
+                    return true;
+                }
+            }
+            
+            if (mActiveSync != null) {
+                AuthorityInfo ainfo = getAuthority(mActiveSync.authorityId);
+                if (ainfo != null && ainfo.account.equals(account)
+                        && ainfo.authority.equals(authority)) {
+                    return true;
+                }
+            }
+        }
+        
+        return false;
+    }
+    
+    public PendingOperation insertIntoPending(PendingOperation op) {
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.v(TAG, "insertIntoPending: account=" + op.account
+                    + " auth=" + op.authority
+                    + " src=" + op.syncSource
+                    + " extras=" + op.extras);
+            
+            AuthorityInfo authority = getOrCreateAuthorityLocked(op.account,
+                    op.authority,
+                    -1 /* desired identifier */,
+                    true /* write accounts to storage */);
+            if (authority == null) {
+                return null;
+            }
+            
+            op = new PendingOperation(op);
+            op.authorityId = authority.ident;
+            mPendingOperations.add(op);
+            appendPendingOperationLocked(op);
+            
+            SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
+            status.pending = true;
+        }
+        
+        reportChange(CHANGE_PENDING);
+        return op;
+    }
+
+    public boolean deleteFromPending(PendingOperation op) {
+        boolean res = false;
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.v(TAG, "deleteFromPending: account=" + op.account
+                    + " auth=" + op.authority
+                    + " src=" + op.syncSource
+                    + " extras=" + op.extras);
+            if (mPendingOperations.remove(op)) {
+                if (mPendingOperations.size() == 0
+                        || mNumPendingFinished >= PENDING_FINISH_TO_WRITE) {
+                    writePendingOperationsLocked();
+                    mNumPendingFinished = 0;
+                } else {
+                    mNumPendingFinished++;
+                }
+                
+                AuthorityInfo authority = getAuthorityLocked(op.account, op.authority,
+                        "deleteFromPending");
+                if (authority != null) {
+                    if (DEBUG) Log.v(TAG, "removing - " + authority);
+                    final int N = mPendingOperations.size();
+                    boolean morePending = false;
+                    for (int i=0; i<N; i++) {
+                        PendingOperation cur = mPendingOperations.get(i);
+                        if (cur.account.equals(op.account)
+                                && cur.authority.equals(op.authority)) {
+                            morePending = true;
+                            break;
+                        }
+                    }
+                    
+                    if (!morePending) {
+                        if (DEBUG) Log.v(TAG, "no more pending!");
+                        SyncStatusInfo status = getOrCreateSyncStatusLocked(authority.ident);
+                        status.pending = false;
+                    }
+                }
+                
+                res = true;
+            }
+        }
+        
+        reportChange(CHANGE_PENDING);
+        return res;
+    }
+
+    public int clearPending() {
+        int num;
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.v(TAG, "clearPending");
+            num = mPendingOperations.size();
+            mPendingOperations.clear();
+            final int N = mSyncStatus.size();
+            for (int i=0; i<N; i++) {
+                mSyncStatus.get(i).pending = false;
+            }
+            writePendingOperationsLocked();
+        }
+        reportChange(CHANGE_PENDING);
+        return num;
+    }
+
+    /**
+     * Return a copy of the current array of pending operations.  The
+     * PendingOperation objects are the real objects stored inside, so that
+     * they can be used with deleteFromPending().
+     */
+    public ArrayList<PendingOperation> getPendingOperations() {
+        synchronized (mAuthorities) {
+            return new ArrayList<PendingOperation>(mPendingOperations);
+        }
+    }
+    
+    /**
+     * Return the number of currently pending operations.
+     */
+    public int getPendingOperationCount() {
+        synchronized (mAuthorities) {
+            return mPendingOperations.size();
+        }
+    }
+    
+    /**
+     * Called when the set of account has changed, given the new array of
+     * active accounts.
+     */
+    public void doDatabaseCleanup(String[] accounts) {
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.w(TAG, "Updating for new accounts...");
+            SparseArray<AuthorityInfo> removing = new SparseArray<AuthorityInfo>();
+            Iterator<AccountInfo> accIt = mAccounts.values().iterator();
+            while (accIt.hasNext()) {
+                AccountInfo acc = accIt.next();
+                if (!ArrayUtils.contains(accounts, acc.account)) {
+                    // This account no longer exists...
+                    if (DEBUG) Log.w(TAG, "Account removed: " + acc.account);
+                    for (AuthorityInfo auth : acc.authorities.values()) {
+                        removing.put(auth.ident, auth);
+                    }
+                    accIt.remove();
+                }
+            }
+            
+            // Clean out all data structures.
+            int i = removing.size();
+            if (i > 0) {
+                while (i > 0) {
+                    i--;
+                    int ident = removing.keyAt(i);
+                    mAuthorities.remove(ident);
+                    int j = mSyncStatus.size();
+                    while (j > 0) {
+                        j--;
+                        if (mSyncStatus.keyAt(j) == ident) {
+                            mSyncStatus.remove(mSyncStatus.keyAt(j));
+                        }
+                    }
+                    j = mSyncHistory.size();
+                    while (j > 0) {
+                        j--;
+                        if (mSyncHistory.get(j).authorityId == ident) {
+                            mSyncHistory.remove(j);
+                        }
+                    }
+                }
+                writeAccountInfoLocked();
+                writeStatusLocked();
+                writePendingOperationsLocked();
+                writeStatisticsLocked();
+            }
+        }
+    }
+
+    /**
+     * Called when the currently active sync is changing (there can only be
+     * one at a time).  Either supply a valid ActiveSyncContext with information
+     * about the sync, or null to stop the currently active sync.
+     */
+    public void setActiveSync(SyncManager.ActiveSyncContext activeSyncContext) {
+        synchronized (mAuthorities) {
+            if (activeSyncContext != null) {
+                if (DEBUG) Log.v(TAG, "setActiveSync: account="
+                        + activeSyncContext.mSyncOperation.account
+                        + " auth=" + activeSyncContext.mSyncOperation.authority
+                        + " src=" + activeSyncContext.mSyncOperation.syncSource
+                        + " extras=" + activeSyncContext.mSyncOperation.extras);
+                if (mActiveSync != null) {
+                    Log.w(TAG, "setActiveSync called with existing active sync!");
+                }
+                AuthorityInfo authority = getAuthorityLocked(
+                        activeSyncContext.mSyncOperation.account,
+                        activeSyncContext.mSyncOperation.authority,
+                        "setActiveSync");
+                if (authority == null) {
+                    return;
+                }
+                mActiveSync = new ActiveSyncInfo(authority.ident,
+                        authority.account, authority.authority,
+                        activeSyncContext.mStartTime);
+            } else {
+                if (DEBUG) Log.v(TAG, "setActiveSync: null");
+                mActiveSync = null;
+            }
+        }
+        
+        reportChange(CHANGE_ACTIVE);
+    }
+
+    /**
+     * To allow others to send active change reports, to poke clients.
+     */
+    public void reportActiveChange() {
+        reportChange(CHANGE_ACTIVE);
+    }
+    
+    /**
+     * Note that sync has started for the given account and authority.
+     */
+    public long insertStartSyncEvent(String accountName, String authorityName,
+            long now, int source) {
+        long id;
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.v(TAG, "insertStartSyncEvent: account=" + accountName
+                    + " auth=" + authorityName + " source=" + source);
+            AuthorityInfo authority = getAuthorityLocked(accountName, authorityName,
+                    "insertStartSyncEvent");
+            if (authority == null) {
+                return -1;
+            }
+            SyncHistoryItem item = new SyncHistoryItem();
+            item.authorityId = authority.ident;
+            item.historyId = mNextHistoryId++;
+            if (mNextHistoryId < 0) mNextHistoryId = 0;
+            item.eventTime = now;
+            item.source = source;
+            item.event = EVENT_START;
+            mSyncHistory.add(0, item);
+            while (mSyncHistory.size() > MAX_HISTORY) {
+                mSyncHistory.remove(mSyncHistory.size()-1);
+            }
+            id = item.historyId;
+            if (DEBUG) Log.v(TAG, "returning historyId " + id);
+        }
+        
+        reportChange(CHANGE_STATUS);
+        return id;
     }
 
     public void stopSyncEvent(long historyId, long elapsedTime, String resultMessage,
             long downstreamActivity, long upstreamActivity) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        db.beginTransaction();
-        try {
-            ContentValues values = new ContentValues();
-            values.put(Sync.History.ELAPSED_TIME, elapsedTime);
-            values.put(Sync.History.EVENT, Sync.History.EVENT_STOP);
-            values.put(Sync.History.MESG, resultMessage);
-            values.put(Sync.History.DOWNSTREAM_ACTIVITY, downstreamActivity);
-            values.put(Sync.History.UPSTREAM_ACTIVITY, upstreamActivity);
-
-            int count = db.update("history", values, "_id=?",
-                    new String[]{Long.toString(historyId)});
-            // We think that count should always be 1 but don't want to change this until after
-            // launch.
-            if (count > 0) {
-                int source = (int) DatabaseUtils.longForQuery(db,
-                        "SELECT source FROM history WHERE _id=" + historyId, null);
-                long eventTime = DatabaseUtils.longForQuery(db,
-                        "SELECT eventTime FROM history WHERE _id=" + historyId, null);
-                long statsId = DatabaseUtils.longForQuery(db,
-                        "SELECT stats_id FROM history WHERE _id=" + historyId, null);
-
-                createStatusRowIfNecessary(statsId);
-
-                // update the status table to reflect this sync
-                StringBuilder sb = new StringBuilder();
-                ArrayList<String> bindArgs = new ArrayList<String>();
-                sb.append("UPDATE status SET");
-                sb.append(" numSyncs=numSyncs+1");
-                sb.append(", totalElapsedTime=totalElapsedTime+" + elapsedTime);
-                switch (source) {
-                    case Sync.History.SOURCE_LOCAL:
-                        sb.append(", numSourceLocal=numSourceLocal+1");
-                        break;
-                    case Sync.History.SOURCE_POLL:
-                        sb.append(", numSourcePoll=numSourcePoll+1");
-                        break;
-                    case Sync.History.SOURCE_USER:
-                        sb.append(", numSourceUser=numSourceUser+1");
-                        break;
-                    case Sync.History.SOURCE_SERVER:
-                        sb.append(", numSourceServer=numSourceServer+1");
-                        break;
+        synchronized (mAuthorities) {
+            if (DEBUG) Log.v(TAG, "stopSyncEvent: historyId=" + historyId);
+            SyncHistoryItem item = null;
+            int i = mSyncHistory.size();
+            while (i > 0) {
+                i--;
+                item = mSyncHistory.get(i);
+                if (item.historyId == historyId) {
+                    break;
                 }
-
-                final String statsIdString = String.valueOf(statsId);
-                final long lastSyncTime = (eventTime + elapsedTime);
-                if (Sync.History.MESG_SUCCESS.equals(resultMessage)) {
-                    // - if successful, update the successful columns
-                    sb.append(", lastSuccessTime=" + lastSyncTime);
-                    sb.append(", lastSuccessSource=" + source);
-                    sb.append(", lastFailureTime=null");
-                    sb.append(", lastFailureSource=null");
-                    sb.append(", lastFailureMesg=null");
-                    sb.append(", initialFailureTime=null");
-                } else if (!Sync.History.MESG_CANCELED.equals(resultMessage)) {
-                    sb.append(", lastFailureTime=" + lastSyncTime);
-                    sb.append(", lastFailureSource=" + source);
-                    sb.append(", lastFailureMesg=?");
-                    bindArgs.add(resultMessage);
-                    long initialFailureTime = DatabaseUtils.longForQuery(db,
-                            SELECT_INITIAL_FAILURE_TIME_QUERY_STRING, 
-                            new String[]{statsIdString, String.valueOf(lastSyncTime)});
-                    sb.append(", initialFailureTime=" + initialFailureTime);
-                }
-                sb.append(" WHERE stats_id=?");
-                bindArgs.add(statsIdString);
-                db.execSQL(sb.toString(), bindArgs.toArray());
-                db.setTransactionSuccessful();
-                mContext.getContentResolver().notifyChange(Sync.History.CONTENT_URI,
-                        null /* observer */);
-                mContext.getContentResolver().notifyChange(Sync.Status.CONTENT_URI,
-                        null /* observer */);
+                item = null;
             }
-        } finally {
-            db.endTransaction();
+            
+            if (item == null) {
+                Log.w(TAG, "stopSyncEvent: no history for id " + historyId);
+                return;
+            }
+            
+            item.elapsedTime = elapsedTime;
+            item.event = EVENT_STOP;
+            item.mesg = resultMessage;
+            item.downstreamActivity = downstreamActivity;
+            item.upstreamActivity = upstreamActivity;
+            
+            SyncStatusInfo status = getOrCreateSyncStatusLocked(item.authorityId);
+            
+            status.numSyncs++;
+            status.totalElapsedTime += elapsedTime;
+            switch (item.source) {
+                case SOURCE_LOCAL:
+                    status.numSourceLocal++;
+                    break;
+                case SOURCE_POLL:
+                    status.numSourcePoll++;
+                    break;
+                case SOURCE_USER:
+                    status.numSourceUser++;
+                    break;
+                case SOURCE_SERVER:
+                    status.numSourceServer++;
+                    break;
+            }
+            
+            boolean writeStatisticsNow = false;
+            int day = getCurrentDay();
+            if (mDayStats[0] == null) {
+                mDayStats[0] = new DayStats(day);
+            } else if (day != mDayStats[0].day) {
+                System.arraycopy(mDayStats, 0, mDayStats, 1, mDayStats.length-1);
+                mDayStats[0] = new DayStats(day);
+                writeStatisticsNow = true;
+            } else if (mDayStats[0] == null) {
+            }
+            final DayStats ds = mDayStats[0];
+            
+            final long lastSyncTime = (item.eventTime + elapsedTime);
+            boolean writeStatusNow = false;
+            if (MESG_SUCCESS.equals(resultMessage)) {
+                // - if successful, update the successful columns
+                if (status.lastSuccessTime == 0 || status.lastFailureTime != 0) {
+                    writeStatusNow = true;
+                }
+                status.lastSuccessTime = lastSyncTime;
+                status.lastSuccessSource = item.source;
+                status.lastFailureTime = 0;
+                status.lastFailureSource = -1;
+                status.lastFailureMesg = null;
+                status.initialFailureTime = 0;
+                ds.successCount++;
+                ds.successTime += elapsedTime;
+            } else if (!MESG_CANCELED.equals(resultMessage)) {
+                if (status.lastFailureTime == 0) {
+                    writeStatusNow = true;
+                }
+                status.lastFailureTime = lastSyncTime;
+                status.lastFailureSource = item.source;
+                status.lastFailureMesg = resultMessage;
+                if (status.initialFailureTime == 0) {
+                    status.initialFailureTime = lastSyncTime;
+                }
+                ds.failureCount++;
+                ds.failureTime += elapsedTime;
+            }
+            
+            if (writeStatusNow) {
+                writeStatusLocked();
+            } else if (!hasMessages(MSG_WRITE_STATUS)) {
+                sendMessageDelayed(obtainMessage(MSG_WRITE_STATUS),
+                        WRITE_STATUS_DELAY);
+            }
+            if (writeStatisticsNow) {
+                writeStatisticsLocked();
+            } else if (!hasMessages(MSG_WRITE_STATISTICS)) {
+                sendMessageDelayed(obtainMessage(MSG_WRITE_STATISTICS),
+                        WRITE_STATISTICS_DELAY);
+            }            
+        }
+        
+        reportChange(CHANGE_STATUS);
+    }
+
+    /**
+     * Return the currently active sync information, or null if there is no
+     * active sync.  Note that the returned object is the real, live active
+     * sync object, so be careful what you do with it.
+     */
+    public ActiveSyncInfo getActiveSync() {
+        synchronized (mAuthorities) {
+            return mActiveSync;
+        }
+    }
+    
+    /**
+     * Return an array of the current sync status for all authorities.  Note
+     * that the objects inside the array are the real, live status objects,
+     * so be careful what you do with them.
+     */
+    public ArrayList<SyncStatusInfo> getSyncStatus() {
+        synchronized (mAuthorities) {
+            final int N = mSyncStatus.size();
+            ArrayList<SyncStatusInfo> ops = new ArrayList<SyncStatusInfo>(N);
+            for (int i=0; i<N; i++) {
+                ops.add(mSyncStatus.valueAt(i));
+            }
+            return ops;
+        }
+    }
+    
+    /**
+     * Returns the status that matches the authority. If there are multiples accounts for
+     * the authority, the one with the latest "lastSuccessTime" status is returned.
+     * @param authority the authority whose row should be selected
+     * @return the SyncStatusInfo for the authority, or null if none exists
+     */
+    public SyncStatusInfo getStatusByAuthority(String authority) {
+        synchronized (mAuthorities) {
+            SyncStatusInfo best = null;
+            final int N = mSyncStatus.size();
+            for (int i=0; i<N; i++) {
+                SyncStatusInfo cur = mSyncStatus.get(i);
+                AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
+                if (ainfo != null && ainfo.authority.equals(authority)) {
+                    if (best == null) {
+                        best = cur;
+                    } else if (best.lastSuccessTime > cur.lastSuccessTime) {
+                        best = cur;
+                    }
+                }
+            }
+            return best;
+        }
+    }
+    
+    /**
+     * Return true if the pending status is true of any matching authorities.
+     */
+    public boolean isAuthorityPending(String account, String authority) {
+        synchronized (mAuthorities) {
+            final int N = mSyncStatus.size();
+            for (int i=0; i<N; i++) {
+                SyncStatusInfo cur = mSyncStatus.get(i);
+                AuthorityInfo ainfo = mAuthorities.get(cur.authorityId);
+                if (ainfo == null) {
+                    continue;
+                }
+                if (account != null && !ainfo.account.equals(account)) {
+                    continue;
+                }
+                if (ainfo.authority.equals(authority) && cur.pending) {
+                    return true;
+                }
+            }
+            return false;
         }
     }
 
     /**
+     * Return an array of the current sync status for all authorities.  Note
+     * that the objects inside the array are the real, live status objects,
+     * so be careful what you do with them.
+     */
+    public ArrayList<SyncHistoryItem> getSyncHistory() {
+        synchronized (mAuthorities) {
+            final int N = mSyncHistory.size();
+            ArrayList<SyncHistoryItem> items = new ArrayList<SyncHistoryItem>(N);
+            for (int i=0; i<N; i++) {
+                items.add(mSyncHistory.get(i));
+            }
+            return items;
+        }
+    }
+    
+    /**
+     * Return an array of the current per-day statistics.  Note
+     * that the objects inside the array are the real, live status objects,
+     * so be careful what you do with them.
+     */
+    public DayStats[] getDayStatistics() {
+        synchronized (mAuthorities) {
+            DayStats[] ds = new DayStats[mDayStats.length];
+            System.arraycopy(mDayStats, 0, ds, 0, ds.length);
+            return ds;
+        }
+    }
+    
+    /**
      * If sync is failing for any of the provider/accounts then determine the time at which it
      * started failing and return the earliest time over all the provider/accounts. If none are
      * failing then return 0.
      */
     public long getInitialSyncFailureTime() {
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        // Join the settings for a provider with the status so that we can easily
-        // check if each provider is enabled for syncing. We also join in the overall
-        // enabled flag ("listen_for_tickles") to each row so that we don't need to
-        // make a separate DB lookup to access it.
-        Cursor c = db.rawQuery(""
-                + "SELECT initialFailureTime, s1.value, s2.value "
-                + "FROM status "
-                + "LEFT JOIN stats ON status.stats_id=stats._id "
-                + "LEFT JOIN settings as s1 ON 'sync_provider_' || authority=s1.name "
-                + "LEFT JOIN settings as s2 ON s2.name='listen_for_tickles' "
-                + "where initialFailureTime is not null "
-                + "  AND lastFailureMesg!=" + Sync.History.ERROR_TOO_MANY_DELETIONS
-                + "  AND lastFailureMesg!=" + Sync.History.ERROR_AUTHENTICATION
-                + "  AND lastFailureMesg!=" + Sync.History.ERROR_SYNC_ALREADY_IN_PROGRESS
-                + "  AND authority!='subscribedfeeds' "
-                + " ORDER BY initialFailureTime", null);
+        synchronized (mAuthorities) {
+            if (!mListenForTickles) {
+                return 0;
+            }
+            
+            long oldest = 0;
+            int i = mSyncStatus.size();
+            while (i > 0) {
+                i--;
+                SyncStatusInfo stats = mSyncStatus.valueAt(i);
+                AuthorityInfo authority = mAuthorities.get(stats.authorityId);
+                if (authority != null && authority.enabled) {
+                    if (oldest == 0 || stats.initialFailureTime < oldest) {
+                        oldest = stats.initialFailureTime;
+                    }
+                }
+            }
+            
+            return oldest;
+        }
+    }
+    
+    private int getCurrentDay() {
+        mCal.setTimeInMillis(System.currentTimeMillis());
+        final int dayOfYear = mCal.get(Calendar.DAY_OF_YEAR);
+        if (mYear != mCal.get(Calendar.YEAR)) {
+            mYear = mCal.get(Calendar.YEAR);
+            mCal.clear();
+            mCal.set(Calendar.YEAR, mYear);
+            mYearInDays = (int)(mCal.getTimeInMillis()/86400000);
+        }
+        return dayOfYear + mYearInDays;
+    }
+    
+    /**
+     * Retrieve an authority, returning null if one does not exist.
+     * 
+     * @param accountName The name of the account for the authority.
+     * @param authorityName The name of the authority itself.
+     * @param tag If non-null, this will be used in a log message if the
+     * requested authority does not exist.
+     */
+    private AuthorityInfo getAuthorityLocked(String accountName, String authorityName,
+            String tag) {
+        AccountInfo account = mAccounts.get(accountName);
+        if (account == null) {
+            if (tag != null) {
+                Log.w(TAG, tag + ": unknown account " + accountName);
+            }
+            return null;
+        }
+        AuthorityInfo authority = account.authorities.get(authorityName);
+        if (authority == null) {
+            if (tag != null) {
+                Log.w(TAG, tag + ": unknown authority " + authorityName);
+            }
+            return null;
+        }
+        
+        return authority;
+    }
+    
+    private AuthorityInfo getOrCreateAuthorityLocked(String accountName,
+            String authorityName, int ident, boolean doWrite) {
+        AccountInfo account = mAccounts.get(accountName);
+        if (account == null) {
+            account = new AccountInfo(accountName);
+            mAccounts.put(accountName, account);
+        }
+        AuthorityInfo authority = account.authorities.get(authorityName);
+        if (authority == null) {
+            if (ident < 0) {
+                // Look for a new identifier for this authority.
+                final int N = mAuthorities.size();
+                ident = 0;
+                for (int i=0; i<N; i++) {
+                    if (mAuthorities.valueAt(i).ident > ident) {
+                        break;
+                    }
+                    ident++;
+                }
+            }
+            authority = new AuthorityInfo(accountName, authorityName, ident);
+            account.authorities.put(authorityName, authority);
+            mAuthorities.put(ident, authority);
+            if (doWrite) {
+                writeAccountInfoLocked();
+            }
+        }
+        
+        return authority;
+    }
+    
+    private SyncStatusInfo getOrCreateSyncStatusLocked(int authorityId) {
+        SyncStatusInfo status = mSyncStatus.get(authorityId);
+        if (status == null) {
+            status = new SyncStatusInfo(authorityId);
+            mSyncStatus.put(authorityId, status);
+        }
+        return status;
+    }
+    
+    /**
+     * Read all account information back in to the initial engine state.
+     */
+    private void readAccountInfoLocked() {
+        FileInputStream fis = null;
         try {
+            fis = mAccountInfoFile.openRead();
+            if (DEBUG_FILE) Log.v(TAG, "Reading " + mAccountInfoFile.getBaseFile());
+            XmlPullParser parser = Xml.newPullParser();
+            parser.setInput(fis, null);
+            int eventType = parser.getEventType();
+            while (eventType != XmlPullParser.START_TAG) {
+                eventType = parser.next();
+            }
+            String tagName = parser.getName();
+            if ("accounts".equals(tagName)) {
+                String listen = parser.getAttributeValue(
+                        null, "listen-for-tickles");
+                mListenForTickles = listen == null
+                            || Boolean.parseBoolean(listen);
+                eventType = parser.next();
+                do {
+                    if (eventType == XmlPullParser.START_TAG
+                            && parser.getDepth() == 2) {
+                        tagName = parser.getName();
+                        if ("authority".equals(tagName)) {
+                            int id = -1;
+                            try {
+                                id = Integer.parseInt(parser.getAttributeValue(
+                                        null, "id"));
+                            } catch (NumberFormatException e) {
+                            } catch (NullPointerException e) {
+                            }
+                            if (id >= 0) {
+                                String accountName = parser.getAttributeValue(
+                                        null, "account");
+                                String authorityName = parser.getAttributeValue(
+                                        null, "authority");
+                                String enabled = parser.getAttributeValue(
+                                        null, "enabled");
+                                AuthorityInfo authority = mAuthorities.get(id); 
+                                if (DEBUG_FILE) Log.v(TAG, "Adding authority: account="
+                                        + accountName + " auth=" + authorityName
+                                        + " enabled=" + enabled);
+                                if (authority == null) {
+                                    if (DEBUG_FILE) Log.v(TAG, "Creating entry");
+                                    authority = getOrCreateAuthorityLocked(
+                                        accountName, authorityName, id, false);
+                                }
+                                if (authority != null) {
+                                    authority.enabled = enabled == null
+                                            || Boolean.parseBoolean(enabled);
+                                } else {
+                                    Log.w(TAG, "Failure adding authority: account="
+                                            + accountName + " auth=" + authorityName
+                                            + " enabled=" + enabled);
+                                }
+                            }
+                        }
+                    }
+                    eventType = parser.next();
+                } while (eventType != XmlPullParser.END_DOCUMENT);
+            }
+        } catch (XmlPullParserException e) {
+            Log.w(TAG, "Error reading accounts", e);
+        } catch (java.io.IOException e) {
+            if (fis == null) Log.i(TAG, "No initial accounts");
+            else Log.w(TAG, "Error reading accounts", e);
+        } finally {
+            if (fis != null) {
+                try {
+                    fis.close();
+                } catch (java.io.IOException e1) {
+                }
+            }
+        }
+    }
+    
+    /**
+     * Write all account information to the account file.
+     */
+    private void writeAccountInfoLocked() {
+        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mAccountInfoFile.getBaseFile());
+        FileOutputStream fos = null;
+        
+        try {
+            fos = mAccountInfoFile.startWrite();
+            XmlSerializer out = new FastXmlSerializer();
+            out.setOutput(fos, "utf-8");
+            out.startDocument(null, true);
+            out.setFeature("http://xmlpull.org/v1/doc/features.html#indent-output", true);
+            
+            out.startTag(null, "accounts");
+            if (!mListenForTickles) {
+                out.attribute(null, "listen-for-tickles", "false");
+            }
+            
+            final int N = mAuthorities.size();
+            for (int i=0; i<N; i++) {
+                AuthorityInfo authority = mAuthorities.get(i);
+                out.startTag(null, "authority");
+                out.attribute(null, "id", Integer.toString(authority.ident));
+                out.attribute(null, "account", authority.account);
+                out.attribute(null, "authority", authority.authority);
+                if (!authority.enabled) {
+                    out.attribute(null, "enabled", "false");
+                }
+                out.endTag(null, "authority");
+            }
+            
+            out.endTag(null, "accounts");
+            
+            out.endDocument();
+            
+            mAccountInfoFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing accounts", e1);
+            if (fos != null) {
+                mAccountInfoFile.failWrite(fos);
+            }
+        }
+    }
+    
+    static int getIntColumn(Cursor c, String name) {
+        return c.getInt(c.getColumnIndex(name));
+    }
+    
+    static long getLongColumn(Cursor c, String name) {
+        return c.getLong(c.getColumnIndex(name));
+    }
+    
+    /**
+     * Load sync engine state from the old syncmanager database, and then
+     * erase it.  Note that we don't deal with pending operations, active
+     * sync, or history.
+     */
+    private void readLegacyAccountInfoLocked() {
+        // Look for old database to initialize from.
+        File file = mContext.getDatabasePath("syncmanager.db");
+        if (!file.exists()) {
+            return;
+        }
+        String path = file.getPath();
+        SQLiteDatabase db = null;
+        try {
+            db = SQLiteDatabase.openDatabase(path, null,
+                    SQLiteDatabase.OPEN_READONLY);
+        } catch (SQLiteException e) {
+        }
+        
+        if (db != null) {
+            // Copy in all of the status information, as well as accounts.
+            if (DEBUG_FILE) Log.v(TAG, "Reading legacy sync accounts db");
+            SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+            qb.setTables("stats, status");
+            HashMap<String,String> map = new HashMap<String,String>();
+            map.put("_id", "status._id as _id");
+            map.put("account", "stats.account as account");
+            map.put("authority", "stats.authority as authority");
+            map.put("totalElapsedTime", "totalElapsedTime");
+            map.put("numSyncs", "numSyncs");
+            map.put("numSourceLocal", "numSourceLocal");
+            map.put("numSourcePoll", "numSourcePoll");
+            map.put("numSourceServer", "numSourceServer");
+            map.put("numSourceUser", "numSourceUser");
+            map.put("lastSuccessSource", "lastSuccessSource");
+            map.put("lastSuccessTime", "lastSuccessTime");
+            map.put("lastFailureSource", "lastFailureSource");
+            map.put("lastFailureTime", "lastFailureTime");
+            map.put("lastFailureMesg", "lastFailureMesg");
+            map.put("pending", "pending");
+            qb.setProjectionMap(map);
+            qb.appendWhere("stats._id = status.stats_id");
+            Cursor c = qb.query(db, null, null, null, null, null, null);
             while (c.moveToNext()) {
-                // these settings default to true, so if they are null treat them as enabled
-                final String providerEnabledString = c.getString(1);
-                if (providerEnabledString != null && !Boolean.parseBoolean(providerEnabledString)) {
-                    continue;
+                String accountName = c.getString(c.getColumnIndex("account"));
+                String authorityName = c.getString(c.getColumnIndex("authority"));
+                AuthorityInfo authority = this.getOrCreateAuthorityLocked(
+                        accountName, authorityName, -1, false);
+                if (authority != null) {
+                    int i = mSyncStatus.size();
+                    boolean found = false;
+                    SyncStatusInfo st = null;
+                    while (i > 0) {
+                        i--;
+                        st = mSyncStatus.get(i);
+                        if (st.authorityId == authority.ident) {
+                            found = true;
+                            break;
+                        }
+                    }
+                    if (!found) {
+                        st = new SyncStatusInfo(authority.ident);
+                        mSyncStatus.put(authority.ident, st);
+                    }
+                    st.totalElapsedTime = getLongColumn(c, "totalElapsedTime");
+                    st.numSyncs = getIntColumn(c, "numSyncs");
+                    st.numSourceLocal = getIntColumn(c, "numSourceLocal");
+                    st.numSourcePoll = getIntColumn(c, "numSourcePoll");
+                    st.numSourceServer = getIntColumn(c, "numSourceServer");
+                    st.numSourceUser = getIntColumn(c, "numSourceUser");
+                    st.lastSuccessSource = getIntColumn(c, "lastSuccessSource");
+                    st.lastSuccessTime = getLongColumn(c, "lastSuccessTime");
+                    st.lastFailureSource = getIntColumn(c, "lastFailureSource");
+                    st.lastFailureTime = getLongColumn(c, "lastFailureTime");
+                    st.lastFailureMesg = c.getString(c.getColumnIndex("lastFailureMesg"));
+                    st.pending = getIntColumn(c, "pending") != 0;
                 }
-                final String allEnabledString = c.getString(2);
-                if (allEnabledString != null && !Boolean.parseBoolean(allEnabledString)) {
-                    continue;
-                }
-                return c.getLong(0);
             }
-        } finally {
+            
             c.close();
-        }
-        return 0;
-    }
-
-    private void createStatusRowIfNecessary(long statsId) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        boolean statusExists = 0 != DatabaseUtils.longForQuery(db,
-                "SELECT count(*) FROM status WHERE stats_id=" + statsId, null);
-        if (!statusExists) {
-            ContentValues values = new ContentValues();
-            values.put("stats_id", statsId);
-            db.insert("status", null, values);
-        }
-    }
-
-    private long createStatsRowIfNecessary(String account, String authority) {
-        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        StringBuilder where = new StringBuilder();
-        where.append(Sync.Stats.ACCOUNT + "= ?");
-        where.append(" and " + Sync.Stats.AUTHORITY + "= ?");
-        Cursor cursor = query(Sync.Stats.CONTENT_URI,
-                Sync.Stats.SYNC_STATS_PROJECTION,
-                where.toString(), new String[] { account, authority },
-                null /* order */);
-        try {
-            long id;
-            if (cursor.moveToFirst()) {
-                id = cursor.getLong(cursor.getColumnIndexOrThrow(Sync.Stats._ID));
-            } else {
-                ContentValues values = new ContentValues();
-                values.put(Sync.Stats.ACCOUNT, account);
-                values.put(Sync.Stats.AUTHORITY, authority);
-                id = db.insert("stats", null, values);
+            
+            // Retrieve the settings.
+            qb = new SQLiteQueryBuilder();
+            qb.setTables("settings");
+            c = qb.query(db, null, null, null, null, null, null);
+            while (c.moveToNext()) {
+                String name = c.getString(c.getColumnIndex("name"));
+                String value = c.getString(c.getColumnIndex("value"));
+                if (name == null) continue;
+                if (name.equals("listen_for_tickles")) {
+                    setListenForNetworkTickles(value == null
+                            || Boolean.parseBoolean(value));
+                } else if (name.startsWith("sync_provider_")) {
+                    String provider = name.substring("sync_provider_".length(),
+                            name.length());
+                    setSyncProviderAutomatically(null, provider,
+                            value == null || Boolean.parseBoolean(value));
+                }
             }
-            return id;
+            
+            c.close();
+            
+            db.close();
+            
+            writeAccountInfoLocked();
+            writeStatusLocked();
+            (new File(path)).delete();
+        }
+    }
+    
+    public static final int STATUS_FILE_END = 0;
+    public static final int STATUS_FILE_ITEM = 100;
+    
+    /**
+     * Read all sync status back in to the initial engine state.
+     */
+    private void readStatusLocked() {
+        if (DEBUG_FILE) Log.v(TAG, "Reading " + mStatusFile.getBaseFile());
+        try {
+            byte[] data = mStatusFile.readFully();
+            Parcel in = Parcel.obtain();
+            in.unmarshall(data, 0, data.length);
+            in.setDataPosition(0);
+            int token;
+            while ((token=in.readInt()) != STATUS_FILE_END) {
+                if (token == STATUS_FILE_ITEM) {
+                    SyncStatusInfo status = new SyncStatusInfo(in);
+                    if (mAuthorities.indexOfKey(status.authorityId) >= 0) {
+                        status.pending = false;
+                        if (DEBUG_FILE) Log.v(TAG, "Adding status for id "
+                                + status.authorityId);
+                        mSyncStatus.put(status.authorityId, status);
+                    }
+                } else {
+                    // Ooops.
+                    Log.w(TAG, "Unknown status token: " + token);
+                    break;
+                }
+            }
+        } catch (java.io.IOException e) {
+            Log.i(TAG, "No initial status");
+        }
+    }
+    
+    /**
+     * Write all sync status to the sync status file.
+     */
+    private void writeStatusLocked() {
+        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatusFile.getBaseFile());
+        
+        // The file is being written, so we don't need to have a scheduled
+        // write until the next change.
+        removeMessages(MSG_WRITE_STATUS);
+        
+        FileOutputStream fos = null;
+        try {
+            fos = mStatusFile.startWrite();
+            Parcel out = Parcel.obtain();
+            final int N = mSyncStatus.size();
+            for (int i=0; i<N; i++) {
+                SyncStatusInfo status = mSyncStatus.valueAt(i);
+                out.writeInt(STATUS_FILE_ITEM);
+                status.writeToParcel(out, 0);
+            }
+            out.writeInt(STATUS_FILE_END);
+            fos.write(out.marshall());
+            out.recycle();
+            
+            mStatusFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing status", e1);
+            if (fos != null) {
+                mStatusFile.failWrite(fos);
+            }
+        }
+    }
+    
+    public static final int PENDING_OPERATION_VERSION = 1;
+    
+    /**
+     * Read all pending operations back in to the initial engine state.
+     */
+    private void readPendingOperationsLocked() {
+        if (DEBUG_FILE) Log.v(TAG, "Reading " + mPendingFile.getBaseFile());
+        try {
+            byte[] data = mPendingFile.readFully();
+            Parcel in = Parcel.obtain();
+            in.unmarshall(data, 0, data.length);
+            in.setDataPosition(0);
+            final int SIZE = in.dataSize();
+            while (in.dataPosition() < SIZE) {
+                int version = in.readInt();
+                if (version != PENDING_OPERATION_VERSION) {
+                    Log.w(TAG, "Unknown pending operation version "
+                            + version + "; dropping all ops");
+                    break;
+                }
+                int authorityId = in.readInt();
+                int syncSource = in.readInt();
+                byte[] flatExtras = in.createByteArray();
+                AuthorityInfo authority = mAuthorities.get(authorityId);
+                if (authority != null) {
+                    Bundle extras = null;
+                    if (flatExtras != null) {
+                        extras = unflattenBundle(flatExtras);
+                    }
+                    PendingOperation op = new PendingOperation(
+                            authority.account, syncSource,
+                            authority.authority, extras);
+                    op.authorityId = authorityId;
+                    op.flatExtras = flatExtras;
+                    if (DEBUG_FILE) Log.v(TAG, "Adding pending op: account=" + op.account
+                            + " auth=" + op.authority
+                            + " src=" + op.syncSource
+                            + " extras=" + op.extras);
+                    mPendingOperations.add(op);
+                }
+            }
+        } catch (java.io.IOException e) {
+            Log.i(TAG, "No initial pending operations");
+        }
+    }
+    
+    private void writePendingOperationLocked(PendingOperation op, Parcel out) {
+        out.writeInt(PENDING_OPERATION_VERSION);
+        out.writeInt(op.authorityId);
+        out.writeInt(op.syncSource);
+        if (op.flatExtras == null && op.extras != null) {
+            op.flatExtras = flattenBundle(op.extras);
+        }
+        out.writeByteArray(op.flatExtras);
+    }
+    
+    /**
+     * Write all currently pending ops to the pending ops file.
+     */
+    private void writePendingOperationsLocked() {
+        final int N = mPendingOperations.size();
+        FileOutputStream fos = null;
+        try {
+            if (N == 0) {
+                if (DEBUG_FILE) Log.v(TAG, "Truncating " + mPendingFile.getBaseFile());
+                mPendingFile.truncate();
+                return;
+            }
+            
+            if (DEBUG_FILE) Log.v(TAG, "Writing new " + mPendingFile.getBaseFile());
+            fos = mPendingFile.startWrite();
+        
+            Parcel out = Parcel.obtain();
+            for (int i=0; i<N; i++) {
+                PendingOperation op = mPendingOperations.get(i);
+                writePendingOperationLocked(op, out);
+            }
+            fos.write(out.marshall());
+            out.recycle();
+            
+            mPendingFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing pending operations", e1);
+            if (fos != null) {
+                mPendingFile.failWrite(fos);
+            }
+        }
+    }
+    
+    /**
+     * Append the given operation to the pending ops file; if unable to,
+     * write all pending ops.
+     */
+    private void appendPendingOperationLocked(PendingOperation op) {
+        if (DEBUG_FILE) Log.v(TAG, "Appending to " + mPendingFile.getBaseFile());
+        FileOutputStream fos = null;
+        try {
+            fos = mPendingFile.openAppend();
+        } catch (java.io.IOException e) {
+            if (DEBUG_FILE) Log.v(TAG, "Failed append; writing full file");
+            writePendingOperationsLocked();
+            return;
+        }
+        
+        try {
+            Parcel out = Parcel.obtain();
+            writePendingOperationLocked(op, out);
+            fos.write(out.marshall());
+            out.recycle();
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing pending operations", e1);
         } finally {
-            cursor.close();
+            try {
+                fos.close();
+            } catch (java.io.IOException e2) {
+            }
+        }
+    }
+    
+    static private byte[] flattenBundle(Bundle bundle) {
+        byte[] flatData = null;
+        Parcel parcel = Parcel.obtain();
+        try {
+            bundle.writeToParcel(parcel, 0);
+            flatData = parcel.marshall();
+        } finally {
+            parcel.recycle();
+        }
+        return flatData;
+    }
+    
+    static private Bundle unflattenBundle(byte[] flatData) {
+        Bundle bundle;
+        Parcel parcel = Parcel.obtain();
+        try {
+            parcel.unmarshall(flatData, 0, flatData.length);
+            parcel.setDataPosition(0);
+            bundle = parcel.readBundle();
+        } catch (RuntimeException e) {
+            // A RuntimeException is thrown if we were unable to parse the parcel.
+            // Create an empty parcel in this case.
+            bundle = new Bundle();
+        } finally {
+            parcel.recycle();
+        }
+        return bundle;
+    }
+    
+    public static final int STATISTICS_FILE_END = 0;
+    public static final int STATISTICS_FILE_ITEM_OLD = 100;
+    public static final int STATISTICS_FILE_ITEM = 101;
+    
+    /**
+     * Read all sync statistics back in to the initial engine state.
+     */
+    private void readStatisticsLocked() {
+        try {
+            byte[] data = mStatisticsFile.readFully();
+            Parcel in = Parcel.obtain();
+            in.unmarshall(data, 0, data.length);
+            in.setDataPosition(0);
+            int token;
+            int index = 0;
+            while ((token=in.readInt()) != STATISTICS_FILE_END) {
+                if (token == STATISTICS_FILE_ITEM
+                        || token == STATISTICS_FILE_ITEM_OLD) {
+                    int day = in.readInt();
+                    if (token == STATISTICS_FILE_ITEM_OLD) {
+                        day = day - 2009 + 14245;  // Magic!
+                    }
+                    DayStats ds = new DayStats(day);
+                    ds.successCount = in.readInt();
+                    ds.successTime = in.readLong();
+                    ds.failureCount = in.readInt();
+                    ds.failureTime = in.readLong();
+                    if (index < mDayStats.length) {
+                        mDayStats[index] = ds;
+                        index++;
+                    }
+                } else {
+                    // Ooops.
+                    Log.w(TAG, "Unknown stats token: " + token);
+                    break;
+                }
+            }
+        } catch (java.io.IOException e) {
+            Log.i(TAG, "No initial statistics");
+        }
+    }
+    
+    /**
+     * Write all sync statistics to the sync status file.
+     */
+    private void writeStatisticsLocked() {
+        if (DEBUG_FILE) Log.v(TAG, "Writing new " + mStatisticsFile.getBaseFile());
+        
+        // The file is being written, so we don't need to have a scheduled
+        // write until the next change.
+        removeMessages(MSG_WRITE_STATISTICS);
+        
+        FileOutputStream fos = null;
+        try {
+            fos = mStatisticsFile.startWrite();
+            Parcel out = Parcel.obtain();
+            final int N = mDayStats.length;
+            for (int i=0; i<N; i++) {
+                DayStats ds = mDayStats[i];
+                if (ds == null) {
+                    break;
+                }
+                out.writeInt(STATISTICS_FILE_ITEM);
+                out.writeInt(ds.day);
+                out.writeInt(ds.successCount);
+                out.writeLong(ds.successTime);
+                out.writeInt(ds.failureCount);
+                out.writeLong(ds.failureTime);
+            }
+            out.writeInt(STATISTICS_FILE_END);
+            fos.write(out.marshall());
+            out.recycle();
+            
+            mStatisticsFile.finishWrite(fos);
+        } catch (java.io.IOException e1) {
+            Log.w(TAG, "Error writing stats", e1);
+            if (fos != null) {
+                mStatisticsFile.failWrite(fos);
+            }
         }
     }
 }
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index 63f6dff..23c0a7bf 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -49,25 +49,35 @@
 public class RemoteCallbackList<E extends IInterface> {
     /*package*/ HashMap<IBinder, Callback> mCallbacks
             = new HashMap<IBinder, Callback>();
-    private IInterface[] mActiveBroadcast;
+    private Object[] mActiveBroadcast;
     private boolean mKilled = false;
     
     private final class Callback implements IBinder.DeathRecipient {
         final E mCallback;
+        final Object mCookie;
         
-        Callback(E callback) {
+        Callback(E callback, Object cookie) {
             mCallback = callback;
+            mCookie = cookie;
         }
         
         public void binderDied() {
             synchronized (mCallbacks) {
                 mCallbacks.remove(mCallback.asBinder());
             }
-            onCallbackDied(mCallback);
+            onCallbackDied(mCallback, mCookie);
         }
     }
     
     /**
+     * Simple version of {@link RemoteCallbackList#register(E, Object)}
+     * that does not take a cookie object.
+     */
+    public boolean register(E callback) {
+        return register(callback, null);
+    }
+    
+    /**
      * Add a new callback to the list.  This callback will remain in the list
      * until a corresponding call to {@link #unregister} or its hosting process
      * goes away.  If the callback was already registered (determined by
@@ -81,6 +91,8 @@
      * Most services will want to check for null before calling this with
      * an object given from a client, so that clients can't crash the
      * service with bad data.
+     * @param cookie Optional additional data to be associated with this
+     * callback.
      * 
      * @return Returns true if the callback was successfully added to the list.
      * Returns false if it was not added, either because {@link #kill} had
@@ -90,14 +102,14 @@
      * @see #kill
      * @see #onCallbackDied
      */
-    public boolean register(E callback) {
+    public boolean register(E callback, Object cookie) {
         synchronized (mCallbacks) {
             if (mKilled) {
                 return false;
             }
             IBinder binder = callback.asBinder();
             try {
-                Callback cb = new Callback(callback);
+                Callback cb = new Callback(callback, cookie);
                 binder.linkToDeath(cb, 0);
                 mCallbacks.put(binder, cb);
                 return true;
@@ -154,17 +166,28 @@
     }
     
     /**
+     * Old version of {@link #onCallbackDied(E, Object)} that
+     * does not provide a cookie.
+     */
+    public void onCallbackDied(E callback) {
+    }
+    
+    /**
      * Called when the process hosting a callback in the list has gone away.
-     * The default implementation does nothing.
+     * The default implementation calls {@link #onCallbackDied(E)}
+     * for backwards compatibility.
      * 
      * @param callback The callback whose process has died.  Note that, since
      * its process has died, you can not make any calls on to this interface.
      * You can, however, retrieve its IBinder and compare it with another
      * IBinder to see if it is the same object.
+     * @param cookie The cookie object original provided to
+     * {@link #register(E, Object)}.
      * 
      * @see #register
      */
-    public void onCallbackDied(E callback) {
+    public void onCallbackDied(E callback, Object cookie) {
+        onCallbackDied(callback);
     }
     
     /**
@@ -203,13 +226,13 @@
             if (N <= 0) {
                 return 0;
             }
-            IInterface[] active = mActiveBroadcast;
+            Object[] active = mActiveBroadcast;
             if (active == null || active.length < N) {
-                mActiveBroadcast = active = new IInterface[N];
+                mActiveBroadcast = active = new Object[N];
             }
             int i=0;
             for (Callback cb : mCallbacks.values()) {
-                active[i++] = cb.mCallback;
+                active[i++] = cb;
             }
             return i;
         }
@@ -237,7 +260,17 @@
      * @see #beginBroadcast
      */
     public E getBroadcastItem(int index) {
-        return (E)mActiveBroadcast[index];
+        return ((Callback)mActiveBroadcast[index]).mCallback;
+    }
+    
+    /**
+     * Retrieve the cookie associated with the item
+     * returned by {@link #getBroadcastItem(int)}.
+     * 
+     * @see #getBroadcastItem
+     */
+    public Object getBroadcastCookie(int index) {
+        return ((Callback)mActiveBroadcast[index]).mCookie;
     }
     
     /**
@@ -248,7 +281,7 @@
      * @see #beginBroadcast
      */
     public void finishBroadcast() {
-        IInterface[] active = mActiveBroadcast;
+        Object[] active = mActiveBroadcast;
         if (active != null) {
             final int N = active.length;
             for (int i=0; i<N; i++) {
diff --git a/core/java/android/provider/Sync.java b/core/java/android/provider/Sync.java
deleted file mode 100644
index 628852f..0000000
--- a/core/java/android/provider/Sync.java
+++ /dev/null
@@ -1,633 +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.provider;
-
-import android.content.ContentQueryMap;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.os.Handler;
-
-import java.util.Map;
-
-/**
- * The Sync provider stores information used in managing the syncing of the device,
- * including the history and pending syncs.
- * 
- * @hide
- */
-public final class Sync {
-    // utility class
-    private Sync() {}
-
-    /**
-     * The content url for this provider.
-     */
-    public static final Uri CONTENT_URI = Uri.parse("content://sync");
-
-    /**
-     * Columns from the stats table.
-     */
-    public interface StatsColumns {
-        /**
-         * The sync account.
-         * <P>Type: TEXT</P>
-         */
-        public static final String ACCOUNT = "account";
-
-        /**
-         * The content authority (contacts, calendar, etc.).
-         * <P>Type: TEXT</P>
-         */
-        public static final String AUTHORITY = "authority";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the stats table.
-     */
-    public static final class Stats implements BaseColumns, StatsColumns {
-
-        // utility class
-        private Stats() {}
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI =
-                Uri.parse("content://sync/stats");
-
-        /** Projection for the _id column in the stats table. */
-        public static final String[] SYNC_STATS_PROJECTION = {_ID};
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface HistoryColumns {
-        /**
-         * The ID of the stats row corresponding to this event.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String STATS_ID = "stats_id";
-
-        /**
-         * The source of the sync event (LOCAL, POLL, USER, SERVER).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String SOURCE = "source";
-
-        /**
-         * The type of sync event (START, STOP).
-         * <P>Type: INTEGER</P>
-         */
-        public static final String EVENT = "event";
-
-        /**
-         * The time of the event.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String EVENT_TIME = "eventTime";
-
-        /**
-         * How long this event took. This is only valid if the EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String ELAPSED_TIME = "elapsedTime";
-
-        /**
-         * Any additional message associated with this event.
-         * <P>Type: TEXT</P>
-         */
-        public static final String MESG = "mesg";
-
-        /**
-         * How much activity was performed sending data to the server. This is sync adapter
-         * specific, but usually is something like how many record update/insert/delete attempts
-         * were carried out. This is only valid if the EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String UPSTREAM_ACTIVITY = "upstreamActivity";
-
-        /**
-         * How much activity was performed while receiving data from the server.
-         * This is sync adapter specific, but usually is something like how many
-         * records were received from the server. This is only valid if the
-         * EVENT is EVENT_STOP.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String DOWNSTREAM_ACTIVITY = "downstreamActivity";
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface StatusColumns {
-        /**
-         * How many syncs were completed for this account and authority.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SYNCS = "numSyncs";
-
-        /**
-         * How long all the events for this account and authority took.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String TOTAL_ELAPSED_TIME = "totalElapsedTime";
-
-        /**
-         * The number of syncs with SOURCE_POLL.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_POLL = "numSourcePoll";
-
-        /**
-         * The number of syncs with SOURCE_SERVER.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_SERVER = "numSourceServer";
-
-        /**
-         * The number of syncs with SOURCE_LOCAL.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_LOCAL = "numSourceLocal";
-
-        /**
-         * The number of syncs with SOURCE_USER.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String NUM_SOURCE_USER = "numSourceUser";
-
-        /**
-         * The time in ms that the last successful sync ended. Will be null if
-         * there are no successful syncs. A successful sync is defined as one having
-         * MESG=MESG_SUCCESS.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_SUCCESS_TIME = "lastSuccessTime";
-
-        /**
-         * The SOURCE of the last successful sync. Will be null if
-         * there are no successful syncs. A successful sync is defined
-         * as one having MESG=MESG_SUCCESS.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_SUCCESS_SOURCE = "lastSuccessSource";
-
-        /**
-         * The end time in ms of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_FAILURE_TIME = "lastFailureTime";
-
-        /**
-         * The SOURCE of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String LAST_FAILURE_SOURCE = "lastFailureSource";
-
-        /**
-         * The MESG of the last sync that failed since the last successful sync.
-         * Will be null if there are no syncs or if the last one succeeded. A failed
-         * sync is defined as one where MESG isn't MESG_SUCCESS or MESG_CANCELED.
-         * <P>Type: STRING</P>
-         */
-        public static final String LAST_FAILURE_MESG = "lastFailureMesg";
-
-        /**
-         * Is set to 1 if a sync is pending, 0 if not.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String PENDING = "pending";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the history
-     * table.
-     */
-    public static class History implements BaseColumns,
-                                                 StatsColumns,
-                                                 HistoryColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI =
-                Uri.parse("content://sync/history");
-
-        /** Enum value for a sync start event. */
-        public static final int EVENT_START = 0;
-
-        /** Enum value for a sync stop event. */
-        public static final int EVENT_STOP = 1;
-
-        // TODO: i18n -- grab these out of resources.
-        /** String names for the sync event types. */
-        public static final String[] EVENTS = { "START", "STOP" };
-
-        /** Enum value for a server-initiated sync. */
-        public static final int SOURCE_SERVER = 0;
-
-        /** Enum value for a local-initiated sync. */
-        public static final int SOURCE_LOCAL = 1;
-        /**
-         * Enum value for a poll-based sync (e.g., upon connection to
-         * network)
-         */
-        public static final int SOURCE_POLL = 2;
-
-        /** Enum value for a user-initiated sync. */
-        public static final int SOURCE_USER = 3;
-
-        // TODO: i18n -- grab these out of resources.
-        /** String names for the sync source types. */
-        public static final String[] SOURCES = { "SERVER",
-                                                 "LOCAL",
-                                                 "POLL",
-                                                 "USER" };
-
-        // Error types
-        public static final int ERROR_SYNC_ALREADY_IN_PROGRESS = 1;
-        public static final int ERROR_AUTHENTICATION = 2;
-        public static final int ERROR_IO = 3;
-        public static final int ERROR_PARSE = 4;
-        public static final int ERROR_CONFLICT = 5;
-        public static final int ERROR_TOO_MANY_DELETIONS = 6;
-        public static final int ERROR_TOO_MANY_RETRIES = 7;
-        public static final int ERROR_INTERNAL = 8;
-
-        // The MESG column will contain one of these or one of the Error types.
-        public static final String MESG_SUCCESS = "success";
-        public static final String MESG_CANCELED = "canceled";
-
-        private static final String FINISHED_SINCE_WHERE_CLAUSE = EVENT + "=" + EVENT_STOP
-                + " AND " + EVENT_TIME + ">? AND " + ACCOUNT + "=? AND " + AUTHORITY + "=?";
-
-        public static String mesgToString(String mesg) {
-            if (MESG_SUCCESS.equals(mesg)) return mesg;
-            if (MESG_CANCELED.equals(mesg)) return mesg;
-            switch (Integer.parseInt(mesg)) {
-                case ERROR_SYNC_ALREADY_IN_PROGRESS: return "already in progress";
-                case ERROR_AUTHENTICATION: return "bad authentication";
-                case ERROR_IO: return "network error";
-                case ERROR_PARSE: return "parse error";
-                case ERROR_CONFLICT: return "conflict detected";
-                case ERROR_TOO_MANY_DELETIONS: return "too many deletions";
-                case ERROR_TOO_MANY_RETRIES: return "too many retries";
-                case ERROR_INTERNAL: return "internal error";
-                default: return "unknown error";
-            }
-        }
-
-        // utility class
-        private History() {}
-
-        /**
-         * returns a cursor that queries the sync history in descending event time order
-         * @param contentResolver the ContentResolver to use for the query
-         * @return the cursor on the History table
-         */
-        public static Cursor query(ContentResolver contentResolver) {
-            return contentResolver.query(CONTENT_URI, null, null, null, EVENT_TIME + " desc");
-        }
-
-        public static boolean hasNewerSyncFinished(ContentResolver contentResolver,
-                String account, String authority, long when) {
-            Cursor c = contentResolver.query(CONTENT_URI, new String[]{_ID},
-                    FINISHED_SINCE_WHERE_CLAUSE,
-                    new String[]{Long.toString(when), account, authority}, null);
-            try {
-              return c.getCount() > 0;
-            } finally {
-                c.close();
-            }
-        }
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the authority history
-     * table, which contains information about syncs aggregated by account and authority.
-     * All the HistoryColumns except for EVENT are present, plus the AuthorityHistoryColumns.
-     */
-    public static class Status extends History implements StatusColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/status");
-
-        // utility class
-        private Status() {}
-
-        /**
-         * returns a cursor that queries the authority sync history in descending event order of
-         * ACCOUNT, AUTHORITY
-         * @param contentResolver the ContentResolver to use for the query
-         * @return the cursor on the AuthorityHistory table
-         */
-        public static Cursor query(ContentResolver contentResolver) {
-            return contentResolver.query(CONTENT_URI, null, null, null, ACCOUNT + ", " + AUTHORITY);
-        }
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver,
-                    boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null),
-                        _ID, keepUpdated, handlerForUpdateNotifications);
-            }
-
-            public ContentValues get(String account, String authority) {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    if (values.getAsString(ACCOUNT).equals(account)
-                            && values.getAsString(AUTHORITY).equals(authority)) {
-                        return values;
-                    }
-                }
-                return null;
-            }
-        }
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the pending syncs table
-     */
-    public static final class Pending implements BaseColumns,
-                                                 StatsColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/pending");
-
-        // utility class
-        private Pending() {}
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
-                        handlerForUpdateNotifications);
-            }
-
-            public boolean isPending(String account, String authority) {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    if (values.getAsString(ACCOUNT).equals(account)
-                            && values.getAsString(AUTHORITY).equals(authority)) {
-                        return true;
-                    }
-                }
-                return false;
-            }
-        }
-    }
-
-    /**
-     * Columns from the history table.
-     */
-    public interface ActiveColumns {
-        /**
-         * The wallclock time of when the active sync started.
-         * <P>Type: INTEGER</P>
-         */
-        public static final String START_TIME = "startTime";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the pending syncs table
-     */
-    public static final class Active implements BaseColumns,
-                                                StatsColumns,
-                                                ActiveColumns {
-
-        /**
-         * The content url for this table.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/active");
-
-        // utility class
-        private Active() {}
-
-        public static class QueryMap extends ContentQueryMap {
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), _ID, keepUpdated,
-                        handlerForUpdateNotifications);
-            }
-
-            public ContentValues getActiveSyncInfo() {
-                Map<String, ContentValues> rows = getRows();
-                for (ContentValues values : rows.values()) {
-                    return values;
-                }
-                return null;
-            }
-
-            public String getSyncingAccount() {
-                ContentValues values = getActiveSyncInfo();
-                return (values == null) ? null : values.getAsString(ACCOUNT);
-            }
-
-            public String getSyncingAuthority() {
-                ContentValues values = getActiveSyncInfo();
-                return (values == null) ? null : values.getAsString(AUTHORITY);
-            }
-
-            public long getSyncStartTime() {
-                ContentValues values = getActiveSyncInfo();
-                return (values == null) ? -1 : values.getAsLong(START_TIME);
-            }
-        }
-    }
-
-    /**
-     * Columns in the settings table, which holds key/value pairs of settings.
-     */
-    public interface SettingsColumns {
-        /**
-         * The key of the setting
-         * <P>Type: TEXT</P>
-         */
-        public static final String KEY = "name";
-
-        /**
-         * The value of the settings
-         * <P>Type: TEXT</P>
-         */
-        public static final String VALUE = "value";
-    }
-
-    /**
-     * Provides constants and utility methods to access and use the settings
-     * table.
-     */
-    public static final class Settings implements BaseColumns, SettingsColumns {
-        /**
-         * The Uri of the settings table. This table behaves a little differently than
-         * normal tables. Updates are not allowed, only inserts, and inserts cause a replace
-         * to be performed, which first deletes the row if it is already present.
-         */
-        public static final Uri CONTENT_URI = Uri.parse("content://sync/settings");
-
-        /** controls whether or not the device listens for sync tickles */
-        public static final String SETTING_LISTEN_FOR_TICKLES = "listen_for_tickles";
-
-        /** controls whether or not the individual provider is synced when tickles are received */
-        public static final String SETTING_SYNC_PROVIDER_PREFIX = "sync_provider_";
-
-        /** query column project */
-        private static final String[] PROJECTION = { KEY, VALUE };
-
-        /**
-         * Convenience function for updating a single settings value as a
-         * boolean. This will either create a new entry in the table if the
-         * given name does not exist, or modify the value of the existing row
-         * with that name.  Note that internally setting values are always
-         * stored as strings, so this function converts the given value to a
-         * string before storing it.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param name The name of the setting to modify.
-         * @param val The new value for the setting.
-         */
-        static private void putBoolean(ContentResolver contentResolver, String name, boolean val) {
-            ContentValues values = new ContentValues();
-            values.put(KEY, name);
-            values.put(VALUE, Boolean.toString(val));
-            // this insert is translated into an update by the underlying Sync provider
-            contentResolver.insert(CONTENT_URI, values);
-        }
-
-        /**
-         * Convenience function for getting a setting value as a boolean without using the
-         * QueryMap for light-weight setting querying.
-         * @param contentResolver The ContentResolver for querying the setting.
-         * @param name The name of the setting to query
-         * @param def The default value for the setting.
-         * @return The value of the setting.
-         */
-        static public boolean getBoolean(ContentResolver contentResolver,
-                String name, boolean def) {
-            Cursor cursor = contentResolver.query(
-                    CONTENT_URI,
-                    PROJECTION,
-                    KEY + "=?",
-                    new String[] { name },
-                    null);
-            try {
-                if (cursor != null && cursor.moveToFirst()) {
-                    return Boolean.parseBoolean(cursor.getString(1));
-                }
-            } finally {
-                if (cursor != null) cursor.close();
-            }
-            return def;
-        }
-
-        /**
-         * A convenience method to set whether or not the provider is synced when
-         * it receives a network tickle.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param providerName the provider whose behavior is being controlled
-         * @param sync true if the provider should be synced when tickles are received for it
-         */
-        static public void setSyncProviderAutomatically(ContentResolver contentResolver,
-                String providerName, boolean sync) {
-            putBoolean(contentResolver, SETTING_SYNC_PROVIDER_PREFIX + providerName, sync);
-        }
-
-        /**
-         * A convenience method to set whether or not the device should listen to tickles.
-         *
-         * @param contentResolver the ContentResolver to use to access the settings table
-         * @param flag true if it should listen.
-         */
-        static public void setListenForNetworkTickles(ContentResolver contentResolver,
-                boolean flag) {
-            putBoolean(contentResolver, SETTING_LISTEN_FOR_TICKLES, flag);
-        }
-
-        public static class QueryMap extends ContentQueryMap {
-            private ContentResolver mContentResolver;
-
-            public QueryMap(ContentResolver contentResolver, boolean keepUpdated,
-                    Handler handlerForUpdateNotifications) {
-                super(contentResolver.query(CONTENT_URI, null, null, null, null), KEY, keepUpdated,
-                        handlerForUpdateNotifications);
-                mContentResolver = contentResolver;
-            }
-
-            /**
-             * Check if the provider should be synced when a network tickle is received
-             * @param providerName the provider whose setting we are querying
-             * @return true of the provider should be synced when a network tickle is received
-             */
-            public boolean getSyncProviderAutomatically(String providerName) {
-                return getBoolean(SETTING_SYNC_PROVIDER_PREFIX + providerName, true);
-            }
-
-            /**
-             * Set whether or not the provider is synced when it receives a network tickle.
-             *
-             * @param providerName the provider whose behavior is being controlled
-             * @param sync true if the provider should be synced when tickles are received for it
-             */
-            public void setSyncProviderAutomatically(String providerName, boolean sync) {
-                Settings.setSyncProviderAutomatically(mContentResolver, providerName, sync);
-            }
-
-            /**
-             * Set whether or not the device should listen for tickles.
-             *
-             * @param flag true if it should listen.
-             */
-            public void setListenForNetworkTickles(boolean flag) {
-                Settings.setListenForNetworkTickles(mContentResolver, flag);
-            }
-
-            /**
-             * Check if the device should listen to tickles.
-
-             * @return true if it should
-             */
-            public boolean getListenForNetworkTickles() {
-                return getBoolean(SETTING_LISTEN_FOR_TICKLES, true);
-            }
-
-            /**
-             * Convenience function for retrieving a single settings value
-             * as a boolean.
-             *
-             * @param name The name of the setting to retrieve.
-             * @param def Value to return if the setting is not defined.
-             * @return The setting's current value, or 'def' if it is not defined.
-             */
-            private boolean getBoolean(String name, boolean def) {
-                ContentValues values = getValues(name);
-                return values != null ? values.getAsBoolean(VALUE) : def;
-            }
-        }
-    }
-}
diff --git a/core/java/com/android/internal/os/AtomicFile.java b/core/java/com/android/internal/os/AtomicFile.java
new file mode 100644
index 0000000..ca0345f
--- /dev/null
+++ b/core/java/com/android/internal/os/AtomicFile.java
@@ -0,0 +1,153 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.os.FileUtils;
+import android.util.Log;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * Helper class for performing atomic operations on a file, by creating a
+ * backup file until a write has successfully completed.
+ */
+public class AtomicFile {
+    private final File mBaseName;
+    private final File mBackupName;
+    
+    public AtomicFile(File baseName) {
+        mBaseName = baseName;
+        mBackupName = new File(baseName.getPath() + ".bak");
+    }
+    
+    public File getBaseFile() {
+        return mBaseName;
+    }
+    
+    public FileOutputStream startWrite() throws IOException {
+        // Rename the current file so it may be used as a backup during the next read
+        if (mBaseName.exists()) {
+            if (!mBaseName.renameTo(mBackupName)) {
+                mBackupName.delete();
+                if (!mBaseName.renameTo(mBackupName)) {
+                    Log.w("AtomicFile", "Couldn't rename file " + mBaseName
+                            + " to backup file " + mBackupName);
+                }
+            }
+        }
+        FileOutputStream str = null;
+        try {
+            str = new FileOutputStream(mBaseName);
+        } catch (FileNotFoundException e) {
+            File parent = mBaseName.getParentFile();
+            if (!parent.mkdir()) {
+                throw new IOException("Couldn't create directory " + mBaseName);
+            }
+            FileUtils.setPermissions(
+                parent.getPath(),
+                FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IXOTH,
+                -1, -1);
+            try {
+                str = new FileOutputStream(mBaseName);
+            } catch (FileNotFoundException e2) {
+                throw new IOException("Couldn't create " + mBaseName);
+            }
+        }
+        return str;
+    }
+    
+    public void finishWrite(FileOutputStream str) {
+        if (str != null) {
+            try {
+                str.close();
+                mBackupName.delete();
+            } catch (IOException e) {
+                Log.w("AtomicFile", "finishWrite: Got exception:", e);
+            }
+        }
+    }
+    
+    public void failWrite(FileOutputStream str) {
+        if (str != null) {
+            try {
+                str.close();
+                mBaseName.delete();
+                mBackupName.renameTo(mBaseName);
+            } catch (IOException e) {
+                Log.w("AtomicFile", "failWrite: Got exception:", e);
+            }
+        }
+    }
+    
+    public FileOutputStream openAppend() throws IOException {
+        try {
+            return new FileOutputStream(mBaseName, true);
+        } catch (FileNotFoundException e) {
+            throw new IOException("Couldn't append " + mBaseName);
+        }
+    }
+    
+    public void truncate() throws IOException {
+        try {
+            FileOutputStream fos = new FileOutputStream(mBaseName);
+            fos.close();
+        } catch (FileNotFoundException e) {
+            throw new IOException("Couldn't append " + mBaseName);
+        } catch (IOException e) {
+        }
+    }
+    
+    public FileInputStream openRead() throws FileNotFoundException {
+        if (mBackupName.exists()) {
+            mBaseName.delete();
+            mBackupName.renameTo(mBaseName);
+        }
+        return new FileInputStream(mBaseName);
+    }
+    
+    public byte[] readFully() throws IOException {
+        FileInputStream stream = openRead();
+        try {
+            int pos = 0;
+            int avail = stream.available();
+            byte[] data = new byte[avail];
+            while (true) {
+                int amt = stream.read(data, pos, data.length-pos);
+                //Log.i("foo", "Read " + amt + " bytes at " + pos
+                //        + " of avail " + data.length);
+                if (amt <= 0) {
+                    //Log.i("foo", "**** FINISHED READING: pos=" + pos
+                    //        + " len=" + data.length);
+                    return data;
+                }
+                pos += amt;
+                avail = stream.available();
+                if (avail > data.length-pos) {
+                    byte[] newData = new byte[pos+avail];
+                    System.arraycopy(data, 0, newData, 0, pos);
+                    data = newData;
+                }
+            }
+        } finally {
+            stream.close();
+        }
+    }
+}
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index aa8fd74..7ebc896 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -1012,9 +1012,6 @@
                 android:excludeFromRecents="true">
         </activity>
 
-        <provider android:name=".content.SyncProvider"
-                android:authorities="sync" android:multiprocess="false" />
-
         <service android:name="com.android.server.LoadAverageService"
             android:exported="true" />
 
diff --git a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
index df599c7..8b3bedf 100644
--- a/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
+++ b/packages/SubscribedFeedsProvider/src/com/android/providers/subscribedfeeds/SubscribedFeedsIntentService.java
@@ -9,7 +9,6 @@
 import android.util.Config;
 import android.util.EventLog;
 import android.app.IntentService;
-import android.provider.Sync;
 import android.provider.SubscribedFeeds;
 import android.provider.SyncConstValue;
 import android.database.Cursor;
@@ -17,7 +16,7 @@
 import android.app.AlarmManager;
 import android.app.PendingIntent;
 import android.os.Bundle;
-import android.os.Debug;
+import android.os.RemoteException;
 import android.text.TextUtils;
 import android.net.Uri;
 
@@ -105,10 +104,6 @@
 
     private void handleTickle(Context context, String account, String feed) {
         Cursor c = null;
-        Sync.Settings.QueryMap syncSettings =
-                new Sync.Settings.QueryMap(context.getContentResolver(),
-                        false /* don't keep updated */,
-                        null /* not needed since keep updated is false */);
         final String where = SubscribedFeeds.Feeds._SYNC_ACCOUNT + "= ? "
                 + "and " + SubscribedFeeds.Feeds.FEED + "= ?";
         try {
@@ -124,9 +119,14 @@
                 String authority = c.getString(c.getColumnIndexOrThrow(
                         SubscribedFeeds.Feeds.AUTHORITY));
                 EventLog.writeEvent(LOG_TICKLE, authority);
-                if (!syncSettings.getSyncProviderAutomatically(authority)) {
-                    Log.d(TAG, "supressing tickle since provider " + authority
-                            + " is configured to not sync automatically");
+                try {
+                    if (!ContentResolver.getContentService()
+                            .getSyncProviderAutomatically(authority)) {
+                        Log.d(TAG, "supressing tickle since provider " + authority
+                                + " is configured to not sync automatically");
+                        continue;
+                    }
+                } catch (RemoteException e) {
                     continue;
                 }
                 Uri uri = Uri.parse("content://" + authority);
@@ -137,7 +137,6 @@
             }
         } finally {
             if (c != null) c.deactivate();
-            syncSettings.close();
         }
     }
 
diff --git a/preloaded-classes b/preloaded-classes
index 7d719e9..0520e41 100644
--- a/preloaded-classes
+++ b/preloaded-classes
@@ -76,8 +76,6 @@
 android.content.ContentQueryMap$1
 android.content.ContentResolver
 android.content.ContentResolver$CursorWrapperInner
-android.content.ContentServiceNative
-android.content.ContentServiceProxy
 android.content.ContentValues
 android.content.Context
 android.content.ContextWrapper
@@ -85,6 +83,8 @@
 android.content.DialogInterface$OnCancelListener
 android.content.DialogInterface$OnDismissListener
 android.content.IContentProvider
+android.content.IContentService
+android.content.IContentService$Stub
 android.content.Intent
 android.content.Intent$1
 android.content.IntentFilter
diff --git a/services/java/com/android/server/ConnectivityService.java b/services/java/com/android/server/ConnectivityService.java
index 760988d..493bd09 100644
--- a/services/java/com/android/server/ConnectivityService.java
+++ b/services/java/com/android/server/ConnectivityService.java
@@ -35,7 +35,6 @@
 import android.os.ServiceManager;
 import android.os.SystemProperties;
 import android.provider.Settings;
-import android.provider.Sync;
 import android.util.EventLog;
 import android.util.Log;
 
diff --git a/test-runner/android/test/SyncBaseInstrumentation.java b/test-runner/android/test/SyncBaseInstrumentation.java
index c1d2507..772d75c 100644
--- a/test-runner/android/test/SyncBaseInstrumentation.java
+++ b/test-runner/android/test/SyncBaseInstrumentation.java
@@ -18,12 +18,10 @@
 
 import android.content.ContentResolver;
 import android.content.Context;
-import android.content.ContentValues;
 import android.os.Bundle;
+import android.os.RemoteException;
 import android.os.SystemClock;
-import android.provider.Sync;
 import android.net.Uri;
-import java.util.Map;
 
 /**
  * If you would like to test sync a single provider with an
@@ -75,11 +73,11 @@
     }
 
     protected void cancelSyncsandDisableAutoSync() {
-        Sync.Settings.QueryMap mSyncSettings =
-                new Sync.Settings.QueryMap(mContentResolver, true, null);
-        mSyncSettings.setListenForNetworkTickles(false);
+        try {
+            ContentResolver.getContentService().setListenForNetworkTickles(false);
+        } catch (RemoteException e) {
+        }
         mContentResolver.cancelSync(null);
-        mSyncSettings.close();
     }
 
     /**
@@ -88,34 +86,11 @@
      * @return
      */
     private boolean isSyncActive(String account, String authority) {
-        Sync.Pending.QueryMap pendingQueryMap = null;
-        Sync.Active.QueryMap activeQueryMap = null;
         try {
-            pendingQueryMap = new Sync.Pending.QueryMap(mContentResolver, false, null);
-            activeQueryMap = new Sync.Active.QueryMap(mContentResolver, false, null);
-
-            if (pendingQueryMap.isPending(account, authority)) {
-                return true;
-            }
-            if (isActiveInActiveQueryMap(activeQueryMap, account, authority)) {
-                return true;
-            }
+            return ContentResolver.getContentService().isSyncActive(account,
+                    authority);
+        } catch (RemoteException e) {
             return false;
-        } finally {
-            activeQueryMap.close();
-            pendingQueryMap.close();
         }
     }
-
-    private boolean isActiveInActiveQueryMap(Sync.Active.QueryMap activemap, String account,
-                                             String authority) {
-        Map<String, ContentValues> rows = activemap.getRows();
-        for (ContentValues values : rows.values()) {
-            if (values.getAsString("account").equals(account)
-                    && values.getAsString("authority").equals(authority)) {
-                return true;
-            }
-        }
-        return false;
-    }
 }
diff --git a/tests/CoreTests/android/content/SyncStorageEngineTest.java b/tests/CoreTests/android/content/SyncStorageEngineTest.java
index 36805b1..dee6e38 100644
--- a/tests/CoreTests/android/content/SyncStorageEngineTest.java
+++ b/tests/CoreTests/android/content/SyncStorageEngineTest.java
@@ -20,7 +20,6 @@
 import android.test.RenamingDelegatingContext;
 import android.test.mock.MockContext;
 import android.test.mock.MockContentResolver;
-import android.provider.Sync;
 
 public class SyncStorageEngineTest extends AndroidTestCase {
 
@@ -39,7 +38,7 @@
 
         long time0 = 1000;
         long historyId = engine.insertStartSyncEvent(
-                account, authority, time0, Sync.History.SOURCE_LOCAL);
+                account, authority, time0, SyncStorageEngine.SOURCE_LOCAL);
         long time1 = time0 + SyncStorageEngine.MILLIS_IN_4WEEKS * 2;
         engine.stopSyncEvent(historyId, time1 - time0, "yay", 0, 0);
     }
diff --git a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
index 727d6f2..cfab90a 100644
--- a/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
+++ b/tools/layoutlib/bridge/src/com/android/layoutlib/bridge/BridgeContentResolver.java
@@ -17,7 +17,6 @@
 package com.android.layoutlib.bridge;
 
 import android.content.ContentResolver;
-import android.content.ContentServiceNative;
 import android.content.Context;
 import android.content.IContentProvider;
 import android.database.ContentObserver;
@@ -51,9 +50,6 @@
     
     /**
      * Stub for the layoutlib bridge content resolver.
-     * <p/>
-     * The super implementation accesses the {@link ContentServiceNative#getDefault()}
-     * which returns null and would make the call crash. Instead we do nothing.
      */
     @Override
     public void registerContentObserver(Uri uri, boolean notifyForDescendents,
@@ -63,9 +59,6 @@
     
     /**
      * Stub for the layoutlib bridge content resolver.
-     * <p/>
-     * The super implementation accesses the {@link ContentServiceNative#getDefault()}
-     * which returns null and would make the call crash. Instead we do nothing.
      */
     @Override
     public void unregisterContentObserver(ContentObserver observer) {
@@ -74,9 +67,6 @@
     
     /**
      * Stub for the layoutlib bridge content resolver.
-     * <p/>
-     * The super implementation accesses the {@link ContentServiceNative#getDefault()}
-     * which returns null and would make the call crash. Instead we do nothing.
      */
     @Override
     public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) {
@@ -85,9 +75,6 @@
     
     /**
      * Stub for the layoutlib bridge content resolver.
-     * <p/>
-     * The super implementation accesses the {@link ContentServiceNative#getDefault()}
-     * which returns null and would make the call crash. Instead we do nothing.
      */
     @Override
     public void startSync(Uri uri, Bundle extras) {
@@ -96,9 +83,6 @@
     
     /**
      * Stub for the layoutlib bridge content resolver.
-     * <p/>
-     * The super implementation accesses the {@link ContentServiceNative#getDefault()}
-     * which returns null and would make the call crash. Instead we do nothing.
      */
     @Override
     public void cancelSync(Uri uri) {
