diff --git a/src/com/android/launcher3/LauncherBackupHelper.java b/src/com/android/launcher3/LauncherBackupHelper.java
index 201f3e9..b2ac577 100644
--- a/src/com/android/launcher3/LauncherBackupHelper.java
+++ b/src/com/android/launcher3/LauncherBackupHelper.java
@@ -15,22 +15,6 @@
  */
 package com.android.launcher3;
 
-import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
-import com.google.protobuf.nano.MessageNano;
-
-import com.android.launcher3.LauncherSettings.Favorites;
-import com.android.launcher3.LauncherSettings.WorkspaceScreens;
-import com.android.launcher3.backup.BackupProtos;
-import com.android.launcher3.backup.BackupProtos.CheckedMessage;
-import com.android.launcher3.backup.BackupProtos.Favorite;
-import com.android.launcher3.backup.BackupProtos.Journal;
-import com.android.launcher3.backup.BackupProtos.Key;
-import com.android.launcher3.backup.BackupProtos.Resource;
-import com.android.launcher3.backup.BackupProtos.Screen;
-import com.android.launcher3.backup.BackupProtos.Widget;
-import com.android.launcher3.compat.UserManagerCompat;
-import com.android.launcher3.compat.UserHandleCompat;
-
 import android.app.backup.BackupDataInputStream;
 import android.app.backup.BackupDataOutput;
 import android.app.backup.BackupHelper;
@@ -42,6 +26,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
+import android.content.pm.PackageManager.NameNotFoundException;
 import android.database.Cursor;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
@@ -51,6 +36,21 @@
 import android.util.Base64;
 import android.util.Log;
 
+import com.android.launcher3.LauncherSettings.Favorites;
+import com.android.launcher3.LauncherSettings.WorkspaceScreens;
+import com.android.launcher3.backup.BackupProtos;
+import com.android.launcher3.backup.BackupProtos.CheckedMessage;
+import com.android.launcher3.backup.BackupProtos.Favorite;
+import com.android.launcher3.backup.BackupProtos.Journal;
+import com.android.launcher3.backup.BackupProtos.Key;
+import com.android.launcher3.backup.BackupProtos.Resource;
+import com.android.launcher3.backup.BackupProtos.Screen;
+import com.android.launcher3.backup.BackupProtos.Widget;
+import com.android.launcher3.compat.UserHandleCompat;
+import com.android.launcher3.compat.UserManagerCompat;
+import com.google.protobuf.nano.InvalidProtocolBufferNanoException;
+import com.google.protobuf.nano.MessageNano;
+
 import java.io.ByteArrayOutputStream;
 import java.io.FileInputStream;
 import java.io.FileOutputStream;
@@ -60,7 +60,6 @@
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.zip.CRC32;
 
 /**
@@ -71,7 +70,6 @@
     private static final String TAG = "LauncherBackupHelper";
     private static final boolean VERBOSE = LauncherBackupAgentHelper.VERBOSE;
     private static final boolean DEBUG = LauncherBackupAgentHelper.DEBUG;
-    private static final boolean DEBUG_PAYLOAD = false;
 
     private static final int MAX_JOURNAL_SIZE = 1000000;
 
@@ -90,27 +88,25 @@
     private static final Bitmap.CompressFormat IMAGE_FORMAT =
             android.graphics.Bitmap.CompressFormat.PNG;
 
-    private static BackupManager sBackupManager;
-
     private static final String[] FAVORITE_PROJECTION = {
-            Favorites._ID,                     // 0
-            Favorites.MODIFIED,                // 1
-            Favorites.INTENT,                  // 2
-            Favorites.APPWIDGET_PROVIDER,      // 3
-            Favorites.APPWIDGET_ID,            // 4
-            Favorites.CELLX,                   // 5
-            Favorites.CELLY,                   // 6
-            Favorites.CONTAINER,               // 7
-            Favorites.ICON,                    // 8
-            Favorites.ICON_PACKAGE,            // 9
-            Favorites.ICON_RESOURCE,           // 10
-            Favorites.ICON_TYPE,               // 11
-            Favorites.ITEM_TYPE,               // 12
-            Favorites.SCREEN,                  // 13
-            Favorites.SPANX,                   // 14
-            Favorites.SPANY,                   // 15
-            Favorites.TITLE,                   // 16
-            Favorites.PROFILE_ID,              // 17
+        Favorites._ID,                     // 0
+        Favorites.MODIFIED,                // 1
+        Favorites.INTENT,                  // 2
+        Favorites.APPWIDGET_PROVIDER,      // 3
+        Favorites.APPWIDGET_ID,            // 4
+        Favorites.CELLX,                   // 5
+        Favorites.CELLY,                   // 6
+        Favorites.CONTAINER,               // 7
+        Favorites.ICON,                    // 8
+        Favorites.ICON_PACKAGE,            // 9
+        Favorites.ICON_RESOURCE,           // 10
+        Favorites.ICON_TYPE,               // 11
+        Favorites.ITEM_TYPE,               // 12
+        Favorites.SCREEN,                  // 13
+        Favorites.SPANX,                   // 14
+        Favorites.SPANY,                   // 15
+        Favorites.TITLE,                   // 16
+        Favorites.PROFILE_ID,              // 17
     };
 
     private static final int ID_INDEX = 0;
@@ -130,37 +126,46 @@
     private static final int SPANX_INDEX = 14;
     private static final int SPANY_INDEX = 15;
     private static final int TITLE_INDEX = 16;
-    private static final int PROFILE_ID_INDEX = 17;
 
     private static final String[] SCREEN_PROJECTION = {
-            WorkspaceScreens._ID,              // 0
-            WorkspaceScreens.MODIFIED,         // 1
-            WorkspaceScreens.SCREEN_RANK       // 2
+        WorkspaceScreens._ID,              // 0
+        WorkspaceScreens.MODIFIED,         // 1
+        WorkspaceScreens.SCREEN_RANK       // 2
     };
 
     private static final int SCREEN_RANK_INDEX = 2;
 
-    private static IconCache mIconCache;
-
     private final Context mContext;
-
-    private final boolean mRestoreEnabled;
-
-    private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
-
+    private final HashSet<String> mExistingKeys;
     private final ArrayList<Key> mKeys;
 
+    private IconCache mIconCache;
+    private BackupManager mBackupManager;
+    private HashMap<ComponentName, AppWidgetProviderInfo> mWidgetMap;
+    private byte[] mBuffer = new byte[512];
+    private long mLastBackupRestoreTime;
+
     public LauncherBackupHelper(Context context, boolean restoreEnabled) {
         mContext = context;
-        mRestoreEnabled = restoreEnabled;
+        mExistingKeys = new HashSet<String>();
         mKeys = new ArrayList<Key>();
     }
 
     private void dataChanged() {
-        if (sBackupManager == null) {
-            sBackupManager = new BackupManager(mContext);
+        if (mBackupManager == null) {
+            mBackupManager = new BackupManager(mContext);
         }
-        sBackupManager.dataChanged();
+        mBackupManager.dataChanged();
+    }
+
+    private void applyJournal(Journal journal) {
+        mLastBackupRestoreTime = journal.t;
+        mExistingKeys.clear();
+        if (journal.key != null) {
+            for (Key key : journal.key) {
+                mExistingKeys.add(keyToBackupKey(key));
+            }
+        }
     }
 
     /**
@@ -181,32 +186,45 @@
         if (VERBOSE) Log.v(TAG, "onBackup");
 
         Journal in = readJournal(oldState);
-        Journal out = new Journal();
+        if (!launcherIsReady()) {
+            // Perform backup later.
+            writeJournal(newState, in);
+            return;
+        }
+        Log.v(TAG, "lastBackupTime = " + in.t);
+        mKeys.clear();
+        applyJournal(in);
 
-        long lastBackupTime = in.t;
-        out.t = System.currentTimeMillis();
-        out.rows = 0;
-        out.bytes = 0;
+        // Record the time before performing backup so that entries edited while the backup
+        // was going on, do not get missed in next backup.
+        long newBackupTime = System.currentTimeMillis();
 
-        Log.v(TAG, "lastBackupTime = " + lastBackupTime);
+        try {
+            backupFavorites(data);
+            backupScreens(data);
+            backupIcons(data);
+            backupWidgets(data);
 
-        ArrayList<Key> keys = new ArrayList<Key>();
-        if (launcherIsReady()) {
-            try {
-                backupFavorites(in, data, out, keys);
-                backupScreens(in, data, out, keys);
-                backupIcons(in, data, out, keys);
-                backupWidgets(in, data, out, keys);
-            } catch (IOException e) {
-                Log.e(TAG, "launcher backup has failed", e);
+            // Delete any key which still exist in the old backup, but is not valid anymore.
+            HashSet<String> validKeys = new HashSet<String>();
+            for (Key key : mKeys) {
+                validKeys.add(keyToBackupKey(key));
             }
-            out.key = keys.toArray(new BackupProtos.Key[keys.size()]);
-        } else {
-            out = in;
+            mExistingKeys.removeAll(validKeys);
+
+            // Delete anything left in the existing keys.
+            for (String deleted: mExistingKeys) {
+                if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
+                data.writeEntityHeader(deleted, -1);
+            }
+
+            mExistingKeys.clear();
+            mLastBackupRestoreTime = newBackupTime;
+        } catch (IOException e) {
+            Log.e(TAG, "launcher backup has failed", e);
         }
 
-        writeJournal(newState, out);
-        Log.v(TAG, "onBackup: wrote " + out.bytes + "b in " + out.rows + " rows.");
+        writeNewStateDescription(newState);
     }
 
     /**
@@ -218,49 +236,41 @@
      */
     @Override
     public void restoreEntity(BackupDataInputStream data) {
-        if (VERBOSE) Log.v(TAG, "restoreEntity");
-        byte[] buffer = new byte[512];
-            String backupKey = data.getKey();
-            int dataSize = data.size();
-            if (buffer.length < dataSize) {
-                buffer = new byte[dataSize];
-            }
-            Key key = null;
-        int bytesRead = 0;
-        try {
-            bytesRead = data.read(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
-        } catch (IOException e) {
-            Log.e(TAG, "failed to read entity from restore data", e);
+        int dataSize = data.size();
+        if (mBuffer.length < dataSize) {
+            mBuffer = new byte[dataSize];
         }
         try {
-            key = backupKeyToKey(backupKey);
+            int bytesRead = data.read(mBuffer, 0, dataSize);
+            if (DEBUG) Log.d(TAG, "read " + bytesRead + " of " + dataSize + " available");
+            String backupKey = data.getKey();
+            Key key = backupKeyToKey(backupKey);
             mKeys.add(key);
             switch (key.type) {
                 case Key.FAVORITE:
-                    restoreFavorite(key, buffer, dataSize, mKeys);
+                    restoreFavorite(key, mBuffer, dataSize);
                     break;
 
                 case Key.SCREEN:
-                    restoreScreen(key, buffer, dataSize, mKeys);
+                    restoreScreen(key, mBuffer, dataSize);
                     break;
 
                 case Key.ICON:
-                    restoreIcon(key, buffer, dataSize, mKeys);
+                    restoreIcon(key, mBuffer, dataSize);
                     break;
 
                 case Key.WIDGET:
-                    restoreWidget(key, buffer, dataSize, mKeys);
+                    restoreWidget(key, mBuffer, dataSize);
                     break;
 
                 default:
                     Log.w(TAG, "unknown restore entity type: " + key.type);
+                    mKeys.remove(key);
                     break;
             }
-        } catch (KeyParsingException e) {
-            Log.w(TAG, "ignoring unparsable backup key: " + backupKey);
+        } catch (IOException e) {
+            Log.w(TAG, "ignoring unparsable backup entry", e);
         }
-
     }
 
     /**
@@ -270,63 +280,55 @@
      */
     @Override
     public void writeNewStateDescription(ParcelFileDescriptor newState) {
-        // clear the output journal time, to force a full backup to
-        // will catch any changes the restore process might have made
-        Journal out = new Journal();
-        out.t = 0;
-        out.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
-        writeJournal(newState, out);
-        Log.v(TAG, "onRestore: read " + mKeys.size() + " rows");
-        mKeys.clear();
+        writeJournal(newState, getCurrentStateJournal());
+    }
+
+    private Journal getCurrentStateJournal() {
+        Journal journal = new Journal();
+        journal.t = mLastBackupRestoreTime;
+        journal.key = mKeys.toArray(new BackupProtos.Key[mKeys.size()]);
+        journal.appVersion = getAppVersion();
+        return journal;
+    }
+
+    private int getAppVersion() {
+        try {
+            return mContext.getPackageManager()
+                    .getPackageInfo(mContext.getPackageName(), 0).versionCode;
+        } catch (NameNotFoundException e) {
+            return 0;
+        }
     }
 
     /**
      * Write all modified favorites to the data stream.
      *
-     *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupFavorites(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys)
-            throws IOException {
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.FAVORITE, in);
-        if (DEBUG) Log.d(TAG, "favorite savedIds.size()=" + savedIds.size());
-
+    private void backupFavorites(BackupDataOutput data) throws IOException {
         // persist things that have changed since the last backup
         ContentResolver cr = mContext.getContentResolver();
         // Don't backup apps in other profiles for now.
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 getUserSelectionArg(), null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
                 final long id = cursor.getLong(ID_INDEX);
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.FAVORITE, id);
-                keys.add(key);
+                mKeys.add(key);
                 final String backupKey = keyToBackupKey(key);
-                currentIds.add(backupKey);
-                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
-                    byte[] blob = packFavorite(cursor);
-                    writeRowToBackup(key, blob, out, data);
+                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+                    writeRowToBackup(key, packFavorite(cursor), data);
                 } else {
-                    if (VERBOSE) Log.v(TAG, "favorite " + id + " was too old: " + updateTime);
+                    if (DEBUG) Log.d(TAG, "favorite already backup up: " + id);
                 }
             }
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "favorite currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -337,74 +339,46 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreFavorite(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreFavorite(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking favorite " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        if (!mRestoreEnabled) {
-            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-            return;
-        }
-
-        try {
-            ContentResolver cr = mContext.getContentResolver();
-            ContentValues values = unpackFavorite(buffer, 0, dataSize);
-            cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode favorite", e);
-        }
+        ContentResolver cr = mContext.getContentResolver();
+        ContentValues values = unpackFavorite(buffer, dataSize);
+        cr.insert(Favorites.CONTENT_URI_NO_NOTIFICATION, values);
     }
 
     /**
      * Write all modified screens to the data stream.
      *
-     *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupScreens(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys)
-            throws IOException {
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.SCREEN, in);
-        if (DEBUG) Log.d(TAG, "screen savedIds.size()=" + savedIds.size());
-
+    private void backupScreens(BackupDataOutput data) throws IOException {
         // persist things that have changed since the last backup
         ContentResolver cr = mContext.getContentResolver();
         Cursor cursor = cr.query(WorkspaceScreens.CONTENT_URI, SCREEN_PROJECTION,
                 null, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
-            if (DEBUG) Log.d(TAG, "dumping screens after: " + in.t);
+            if (DEBUG) Log.d(TAG, "dumping screens after: " + mLastBackupRestoreTime);
             while(cursor.moveToNext()) {
                 final long id = cursor.getLong(ID_INDEX);
                 final long updateTime = cursor.getLong(ID_MODIFIED);
                 Key key = getKey(Key.SCREEN, id);
-                keys.add(key);
+                mKeys.add(key);
                 final String backupKey = keyToBackupKey(key);
-                currentIds.add(backupKey);
-                if (!savedIds.contains(backupKey) || updateTime >= in.t) {
-                    byte[] blob = packScreen(cursor);
-                    writeRowToBackup(key, blob, out, data);
+                if (!mExistingKeys.contains(backupKey) || updateTime >= mLastBackupRestoreTime) {
+                    writeRowToBackup(key, packScreen(cursor), data);
                 } else {
-                    if (VERBOSE) Log.v(TAG, "screen " + id + " was too old: " + updateTime);
+                    if (VERBOSE) Log.v(TAG, "screen already backup up " + id);
                 }
             }
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "screen currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -415,40 +389,24 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreScreen(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreScreen(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking screen " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        if (!mRestoreEnabled) {
-            if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-            return;
-        }
-
-        try {
-            ContentResolver cr = mContext.getContentResolver();
-            ContentValues values = unpackScreen(buffer, 0, dataSize);
-            cr.insert(WorkspaceScreens.CONTENT_URI, values);
-
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode screen", e);
-        }
+        ContentResolver cr = mContext.getContentResolver();
+        ContentValues values = unpackScreen(buffer, dataSize);
+        cr.insert(WorkspaceScreens.CONTENT_URI, values);
     }
 
     /**
      * Write all the static icon resources we need to render placeholders
      * for a package that is not installed.
      *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
-     * @throws IOException
      */
-    private void backupIcons(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys) throws IOException {
+    private void backupIcons(BackupDataOutput data) throws IOException {
         // persist icons that haven't been persisted yet
         if (!initializeIconCache()) {
             dataChanged(); // try again later
@@ -458,21 +416,14 @@
         final ContentResolver cr = mContext.getContentResolver();
         final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
         final UserHandleCompat myUserHandle = UserHandleCompat.myUserHandle();
-
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.ICON, in);
-        if (DEBUG) Log.d(TAG, "icon savedIds.size()=" + savedIds.size());
+        int backupUpIconCount = 0;
 
         // Don't backup apps in other profiles for now.
-        int startRows = out.rows;
-        if (DEBUG) Log.d(TAG, "starting here: " + startRows);
-
         String where = "(" + Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPLICATION + " OR " +
                 Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_SHORTCUT + ") AND " +
                 getUserSelectionArg();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 where, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
@@ -486,27 +437,26 @@
                     if (cn != null) {
                         key = getKey(Key.ICON, cn.flattenToShortString());
                         backupKey = keyToBackupKey(key);
-                        currentIds.add(backupKey);
                     } else {
                         Log.w(TAG, "empty intent on application favorite: " + id);
                     }
-                    if (savedIds.contains(backupKey)) {
-                        if (VERBOSE) Log.v(TAG, "already saved icon " + backupKey);
+                    if (mExistingKeys.contains(backupKey)) {
+                        if (DEBUG) Log.d(TAG, "already saved icon " + backupKey);
 
                         // remember that we already backed this up previously
-                        keys.add(key);
+                        mKeys.add(key);
                     } else if (backupKey != null) {
-                        if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
-                        if ((out.rows - startRows) < MAX_ICONS_PER_PASS) {
-                            if (VERBOSE) Log.v(TAG, "saving icon " + backupKey);
+                        if (DEBUG) Log.d(TAG, "I can count this high: " + backupUpIconCount);
+                        if (backupUpIconCount < MAX_ICONS_PER_PASS) {
+                            if (DEBUG) Log.d(TAG, "saving icon " + backupKey);
                             Bitmap icon = mIconCache.getIcon(intent, myUserHandle);
-                            keys.add(key);
                             if (icon != null && !mIconCache.isDefaultIcon(icon, myUserHandle)) {
-                                byte[] blob = packIcon(dpi, icon);
-                                writeRowToBackup(key, blob, out, data);
+                                writeRowToBackup(key, packIcon(dpi, icon), data);
+                                mKeys.add(key);
+                                backupUpIconCount ++;
                             }
                         } else {
-                            if (VERBOSE) Log.d(TAG, "deferring icon backup " + backupKey);
+                            if (VERBOSE) Log.v(TAG, "deferring icon backup " + backupKey);
                             // too many icons for this pass, request another.
                             dataChanged();
                         }
@@ -521,11 +471,6 @@
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "icon currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -536,55 +481,32 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreIcon(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreIcon(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking icon " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
 
-        try {
-            Resource res = unpackIcon(buffer, 0, dataSize);
-            if (DEBUG) {
-                Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
-            }
-            if (DEBUG_PAYLOAD) {
-                Log.d(TAG, "read " +
-                        Base64.encodeToString(res.data, 0, res.data.length,
-                                Base64.NO_WRAP));
-            }
-            Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
-            if (icon == null) {
-                Log.w(TAG, "failed to unpack icon for " + key.name);
-            }
-
-            if (!mRestoreEnabled) {
-                if (VERBOSE) {
-                    Log.v(TAG, "restore not enabled: skipping database mutation");
-                }
-                return;
-            } else {
-                if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
-                IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name),
-                        icon, res.dpi);
-            }
-        } catch (IOException e) {
-            Log.d(TAG, "failed to save restored icon for: " + key.name, e);
+        Resource res = unpackProto(new Resource(), buffer, dataSize);
+        if (DEBUG) {
+            Log.d(TAG, "unpacked " + res.dpi + " dpi icon");
         }
+        Bitmap icon = BitmapFactory.decodeByteArray(res.data, 0, res.data.length);
+        if (icon == null) {
+            Log.w(TAG, "failed to unpack icon for " + key.name);
+        }
+        if (VERBOSE) Log.v(TAG, "saving restored icon as: " + key.name);
+        IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(key.name), icon, res.dpi);
     }
 
     /**
      * Write all the static widget resources we need to render placeholders
      * for a package that is not installed.
      *
-     * @param in notes from last backup
      * @param data output stream for key/value pairs
-     * @param out notes about this backup
-     * @param keys keys to mark as clean in the notes for next backup
      * @throws IOException
      */
-    private void backupWidgets(Journal in, BackupDataOutput data, Journal out,
-            ArrayList<Key> keys) throws IOException {
+    private void backupWidgets(BackupDataOutput data) throws IOException {
         // persist static widget info that hasn't been persisted yet
         final LauncherAppState appState = LauncherAppState.getInstanceNoCreate();
         if (appState == null || !initializeIconCache()) {
@@ -597,18 +519,12 @@
         final int dpi = mContext.getResources().getDisplayMetrics().densityDpi;
         final DeviceProfile profile = appState.getDynamicGrid().getDeviceProfile();
         if (DEBUG) Log.d(TAG, "cellWidthPx: " + profile.cellWidthPx);
+        int backupWidgetCount = 0;
 
-        // read the old ID set
-        Set<String> savedIds = getSavedIdsByType(Key.WIDGET, in);
-        if (DEBUG) Log.d(TAG, "widgets savedIds.size()=" + savedIds.size());
-
-        int startRows = out.rows;
-        if (DEBUG) Log.d(TAG, "starting here: " + startRows);
         String where = Favorites.ITEM_TYPE + "=" + Favorites.ITEM_TYPE_APPWIDGET + " AND "
                 + getUserSelectionArg();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION,
                 where, null, null);
-        Set<String> currentIds = new HashSet<String>(cursor.getCount());
         try {
             cursor.moveToPosition(-1);
             while(cursor.moveToNext()) {
@@ -622,27 +538,25 @@
                 if (provider != null) {
                     key = getKey(Key.WIDGET, providerName);
                     backupKey = keyToBackupKey(key);
-                    currentIds.add(backupKey);
                 } else {
                     Log.w(TAG, "empty intent on appwidget: " + id);
                 }
-                if (savedIds.contains(backupKey)) {
-                    if (VERBOSE) Log.v(TAG, "already saved widget " + backupKey);
+                if (mExistingKeys.contains(backupKey)) {
+                    if (DEBUG) Log.d(TAG, "already saved widget " + backupKey);
 
                     // remember that we already backed this up previously
-                    keys.add(key);
+                    mKeys.add(key);
                 } else if (backupKey != null) {
-                    if (DEBUG) Log.d(TAG, "I can count this high: " + out.rows);
-                    if ((out.rows - startRows) < MAX_WIDGETS_PER_PASS) {
-                        if (VERBOSE) Log.v(TAG, "saving widget " + backupKey);
+                    if (DEBUG) Log.d(TAG, "I can count this high: " + backupWidgetCount);
+                    if (backupWidgetCount < MAX_WIDGETS_PER_PASS) {
+                        if (DEBUG) Log.d(TAG, "saving widget " + backupKey);
                         previewLoader.setPreviewSize(spanX * profile.cellWidthPx,
                                 spanY * profile.cellHeightPx, widgetSpacingLayout);
-                        byte[] blob = packWidget(dpi, previewLoader, mIconCache, provider);
-                        keys.add(key);
-                        writeRowToBackup(key, blob, out, data);
-
+                        writeRowToBackup(key, packWidget(dpi, previewLoader, mIconCache, provider), data);
+                        mKeys.add(key);
+                        backupWidgetCount ++;
                     } else {
-                        if (VERBOSE) Log.d(TAG, "deferring widget backup " + backupKey);
+                        if (VERBOSE) Log.v(TAG, "deferring widget backup " + backupKey);
                         // too many widgets for this pass, request another.
                         dataChanged();
                     }
@@ -651,11 +565,6 @@
         } finally {
             cursor.close();
         }
-        if (DEBUG) Log.d(TAG, "widget currentIds.size()=" + currentIds.size());
-
-        // these IDs must have been deleted
-        savedIds.removeAll(currentIds);
-        out.rows += removeDeletedKeysFromBackup(savedIds, data);
     }
 
     /**
@@ -666,35 +575,25 @@
      * @param key identifier for the row
      * @param buffer the serialized proto from the stream, may be larger than dataSize
      * @param dataSize the size of the proto from the stream
-     * @param keys keys to mark as clean in the notes for next backup
      */
-    private void restoreWidget(Key key, byte[] buffer, int dataSize, ArrayList<Key> keys) {
+    private void restoreWidget(Key key, byte[] buffer, int dataSize) throws IOException {
         if (VERBOSE) Log.v(TAG, "unpacking widget " + key.id);
         if (DEBUG) Log.d(TAG, "read (" + buffer.length + "): " +
                 Base64.encodeToString(buffer, 0, dataSize, Base64.NO_WRAP));
-        try {
-            Widget widget = unpackWidget(buffer, 0, dataSize);
-            if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
-            if (widget.icon.data != null)  {
-                Bitmap icon = BitmapFactory
-                        .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
-                if (icon == null) {
-                    Log.w(TAG, "failed to unpack widget icon for " + key.name);
-                } else {
-                    IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
-                            icon, widget.icon.dpi);
-                }
-            }
-
-            if (!mRestoreEnabled) {
-                if (VERBOSE) Log.v(TAG, "restore not enabled: skipping database mutation");
-                return;
+        Widget widget = unpackProto(new Widget(), buffer, dataSize);
+        if (DEBUG) Log.d(TAG, "unpacked " + widget.provider);
+        if (widget.icon.data != null)  {
+            Bitmap icon = BitmapFactory
+                    .decodeByteArray(widget.icon.data, 0, widget.icon.data.length);
+            if (icon == null) {
+                Log.w(TAG, "failed to unpack widget icon for " + key.name);
             } else {
-                // future site of widget table mutation
+                IconCache.preloadIcon(mContext, ComponentName.unflattenFromString(widget.provider),
+                        icon, widget.icon.dpi);
             }
-        } catch (InvalidProtocolBufferNanoException e) {
-            Log.e(TAG, "failed to decode widget", e);
         }
+
+        // future site of widget table mutation
     }
 
     /** create a new key, with an integer ID.
@@ -744,30 +643,6 @@
         }
     }
 
-    private String getKeyName(Key key) {
-        if (TextUtils.isEmpty(key.name)) {
-            return Long.toString(key.id);
-        } else {
-            return key.name;
-        }
-
-    }
-
-    private String geKeyType(Key key) {
-        switch (key.type) {
-            case Key.FAVORITE:
-                return "favorite";
-            case Key.SCREEN:
-                return "screen";
-            case Key.ICON:
-                return "icon";
-            case Key.WIDGET:
-                return "widget";
-            default:
-                return "anonymous";
-        }
-    }
-
     /** Compute the checksum over the important bits of a key. */
     private long checkKey(Key key) {
         CRC32 checksum = new CRC32();
@@ -781,7 +656,7 @@
     }
 
     /** Serialize a Favorite for persistence, including a checksum wrapper. */
-    private byte[] packFavorite(Cursor c) {
+    private Favorite packFavorite(Cursor c) {
         Favorite favorite = new Favorite();
         favorite.id = c.getLong(ID_INDEX);
         favorite.screen = c.getInt(SCREEN_INDEX);
@@ -819,7 +694,7 @@
                 favorite.intent = intent.toUri(0);
             } catch (URISyntaxException e) {
                 Log.e(TAG, "Invalid intent", e);
-           }
+            }
         }
         favorite.itemType = c.getInt(ITEM_TYPE_INDEX);
         if (favorite.itemType == Favorites.ITEM_TYPE_APPWIDGET) {
@@ -830,16 +705,13 @@
             }
         }
 
-        return writeCheckedBytes(favorite);
+        return favorite;
     }
 
     /** Deserialize a Favorite from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackFavorite(byte[] buffer, int offset, int dataSize)
+    private ContentValues unpackFavorite(byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
-        Favorite favorite = new Favorite();
-        MessageNano.mergeFrom(favorite, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked favorite " + favorite.itemType + ", " +
-                (TextUtils.isEmpty(favorite.title) ? favorite.id : favorite.title));
+        Favorite favorite = unpackProto(new Favorite(), buffer, dataSize);
         ContentValues values = new ContentValues();
         values.put(Favorites._ID, favorite.id);
         values.put(Favorites.SCREEN, favorite.screen);
@@ -889,20 +761,17 @@
     }
 
     /** Serialize a Screen for persistence, including a checksum wrapper. */
-    private byte[] packScreen(Cursor c) {
+    private Screen packScreen(Cursor c) {
         Screen screen = new Screen();
         screen.id = c.getLong(ID_INDEX);
         screen.rank = c.getInt(SCREEN_RANK_INDEX);
-
-        return writeCheckedBytes(screen);
+        return screen;
     }
 
     /** Deserialize a Screen from persistence, after verifying checksum wrapper. */
-    private ContentValues unpackScreen(byte[] buffer, int offset, int dataSize)
+    private ContentValues unpackScreen(byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
-        Screen screen = new Screen();
-        MessageNano.mergeFrom(screen, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked screen " + screen.id + "/" + screen.rank);
+        Screen screen = unpackProto(new Screen(), buffer, dataSize);
         ContentValues values = new ContentValues();
         values.put(WorkspaceScreens._ID, screen.id);
         values.put(WorkspaceScreens.SCREEN_RANK, screen.rank);
@@ -910,27 +779,18 @@
     }
 
     /** Serialize an icon Resource for persistence, including a checksum wrapper. */
-    private byte[] packIcon(int dpi, Bitmap icon) {
+    private Resource packIcon(int dpi, Bitmap icon) {
         Resource res = new Resource();
         res.dpi = dpi;
         ByteArrayOutputStream os = new ByteArrayOutputStream();
         if (icon.compress(IMAGE_FORMAT, IMAGE_COMPRESSION_QUALITY, os)) {
             res.data = os.toByteArray();
         }
-        return writeCheckedBytes(res);
-    }
-
-    /** Deserialize an icon resource from persistence, after verifying checksum wrapper. */
-    private static Resource unpackIcon(byte[] buffer, int offset, int dataSize)
-            throws InvalidProtocolBufferNanoException {
-        Resource res = new Resource();
-        MessageNano.mergeFrom(res, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked icon " + res.dpi + "/" + res.data.length);
         return res;
     }
 
     /** Serialize a widget for persistence, including a checksum wrapper. */
-    private byte[] packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
+    private Widget packWidget(int dpi, WidgetPreviewLoader previewLoader, IconCache iconCache,
             ComponentName provider) {
         final AppWidgetProviderInfo info = findAppWidgetProviderInfo(provider);
         Widget widget = new Widget();
@@ -956,16 +816,17 @@
                 widget.preview.dpi = dpi;
             }
         }
-        return writeCheckedBytes(widget);
+        return widget;
     }
 
-    /** Deserialize a widget from persistence, after verifying checksum wrapper. */
-    private Widget unpackWidget(byte[] buffer, int offset, int dataSize)
+    /**
+     * Deserialize a proto after verifying checksum wrapper.
+     */
+    private <T extends MessageNano> T unpackProto(T proto, byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
-        Widget widget = new Widget();
-        MessageNano.mergeFrom(widget, readCheckedBytes(buffer, offset, dataSize));
-        if (VERBOSE) Log.v(TAG, "unpacked widget " + widget.provider);
-        return widget;
+        MessageNano.mergeFrom(proto, readCheckedBytes(buffer, dataSize));
+        if (DEBUG) Log.d(TAG, "unpacked proto " + proto);
+        return proto;
     }
 
     /**
@@ -1001,9 +862,6 @@
                         if (result > 0) {
                             availableBytes -= result;
                             bytesRead += result;
-                            if (DEBUG && (bytesRead % 100 == 0)) {
-                                Log.d(TAG, "read some bytes: " + bytesRead);
-                            }
                         } else {
                             Log.w(TAG, "unexpected end of file while reading journal.");
                             // stop reading and see what there is to parse
@@ -1016,7 +874,7 @@
 
                     // check the buffer to see if we have a valid journal
                     try {
-                        MessageNano.mergeFrom(journal, readCheckedBytes(buffer, 0, bytesRead));
+                        MessageNano.mergeFrom(journal, readCheckedBytes(buffer, bytesRead));
                         // if we are here, then we have read a valid, checksum-verified journal
                         valid = true;
                         availableBytes = 0;
@@ -1044,46 +902,18 @@
         return journal;
     }
 
-    private void writeRowToBackup(Key key, byte[] blob, Journal out,
+
+    private void writeRowToBackup(Key key, MessageNano proto, BackupDataOutput data)
+            throws IOException {
+        writeRowToBackup(keyToBackupKey(key), proto, data);
+    }
+
+    private void writeRowToBackup(String backupKey, MessageNano proto,
             BackupDataOutput data) throws IOException {
-        String backupKey = keyToBackupKey(key);
+        byte[] blob = writeCheckedBytes(proto);
         data.writeEntityHeader(backupKey, blob.length);
         data.writeEntityData(blob, blob.length);
-        out.rows++;
-        out.bytes += blob.length;
-        if (VERBOSE) Log.v(TAG, "saving " + geKeyType(key) + " " + backupKey + ": " +
-                getKeyName(key) + "/" + blob.length);
-        if(DEBUG_PAYLOAD) {
-            String encoded = Base64.encodeToString(blob, 0, blob.length, Base64.NO_WRAP);
-            final int chunkSize = 1024;
-            for (int offset = 0; offset < encoded.length(); offset += chunkSize) {
-                int end = offset + chunkSize;
-                end = Math.min(end, encoded.length());
-                Log.w(TAG, "wrote " + encoded.substring(offset, end));
-            }
-        }
-    }
-
-    private Set<String> getSavedIdsByType(int type, Journal in) {
-        Set<String> savedIds = new HashSet<String>();
-        for(int i = 0; i < in.key.length; i++) {
-            Key key = in.key[i];
-            if (key.type == type) {
-                savedIds.add(keyToBackupKey(key));
-            }
-        }
-        return savedIds;
-    }
-
-    private int removeDeletedKeysFromBackup(Set<String> deletedIds, BackupDataOutput data)
-            throws IOException {
-        int rows = 0;
-        for(String deleted: deletedIds) {
-            if (VERBOSE) Log.v(TAG, "dropping deleted item " + deleted);
-            data.writeEntityHeader(deleted, -1);
-            rows++;
-        }
-        return rows;
+        if (VERBOSE) Log.v(TAG, "Writing New entry " + backupKey);
     }
 
     /**
@@ -1119,10 +949,10 @@
     }
 
     /** Unwrap a proto message from a CheckedMessage, verifying the checksum. */
-    private static byte[] readCheckedBytes(byte[] buffer, int offset, int dataSize)
+    private static byte[] readCheckedBytes(byte[] buffer, int dataSize)
             throws InvalidProtocolBufferNanoException {
         CheckedMessage wrapper = new CheckedMessage();
-        MessageNano.mergeFrom(wrapper, buffer, offset, dataSize);
+        MessageNano.mergeFrom(wrapper, buffer, 0, dataSize);
         CRC32 checksum = new CRC32();
         checksum.update(wrapper.payload);
         if (wrapper.checksum != checksum.getValue()) {
@@ -1161,7 +991,9 @@
     }
 
 
-   // check if the launcher is in a state to support backup
+    /**
+     * @return true if the launcher is in a state to support backup
+     */
     private boolean launcherIsReady() {
         ContentResolver cr = mContext.getContentResolver();
         Cursor cursor = cr.query(Favorites.CONTENT_URI, FAVORITE_PROJECTION, null, null, null);
@@ -1185,7 +1017,7 @@
                 .getSerialNumberForUser(UserHandleCompat.myUserHandle());
     }
 
-    private class KeyParsingException extends Throwable {
+    private class KeyParsingException extends IOException {
         private KeyParsingException(Throwable cause) {
             super(cause);
         }
