diff --git a/src.zip b/src.zip
deleted file mode 100644
index ddc6415..0000000
--- a/src.zip
+++ /dev/null
Binary files differ
diff --git a/src/com/cooliris/cache/BootReceiver.java b/src/com/cooliris/cache/BootReceiver.java
index 311f3da..dae5355 100644
--- a/src/com/cooliris/cache/BootReceiver.java
+++ b/src/com/cooliris/cache/BootReceiver.java
@@ -1,19 +1,25 @@
 package com.cooliris.cache;
 
-import com.cooliris.media.Gallery;
+import com.cooliris.media.LocalDataSource;
 import com.cooliris.media.SingleDataSource;
 
 import android.content.BroadcastReceiver;
+import android.content.ContentResolver;
 import android.content.Context;
 import android.content.Intent;
+import android.database.ContentObserver;
 import android.net.Uri;
+import android.os.Handler;
+import android.provider.MediaStore.Images;
+import android.provider.MediaStore.Video;
 import android.util.Log;
 
 public class BootReceiver extends BroadcastReceiver {
-    private static final String TAG = "BootReceiver"; 
+    private static final String TAG = "BootReceiver";
+    private final Handler mHandler = new Handler();
 
     @Override
-    public void onReceive(Context context, Intent intent) {
+    public void onReceive(final Context context, Intent intent) {
         final String action = intent.getAction();
         Log.i(TAG, "Got intent with action " + action);
         if (Intent.ACTION_MEDIA_SCANNER_FINISHED.equals(action)) {
@@ -29,7 +35,21 @@
                 CacheService.markDirty(context);
             }
         } else if (action.equals(Intent.ACTION_BOOT_COMPLETED)) {
-            Gallery.NEEDS_REFRESH = true;
+            // We add special listeners for the MediaProvider
+            final Handler handler = mHandler;
+            final ContentObserver localObserver = new ContentObserver(handler) {
+                public void onChange(boolean selfChange) {
+                    if (!LocalDataSource.sObserverActive) {
+                    	CacheService.senseDirty(context, null);
+                    }
+                }
+            };
+            // Start listening perpetually.
+            Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
+            Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
+            ContentResolver cr = context.getContentResolver();
+            cr.registerContentObserver(uriImages, false, localObserver);
+            cr.registerContentObserver(uriVideos, false, localObserver);
         }
     }
 }
diff --git a/src/com/cooliris/cache/CacheService.java b/src/com/cooliris/cache/CacheService.java
index f3e610f..d54f9fa 100644
--- a/src/com/cooliris/cache/CacheService.java
+++ b/src/com/cooliris/cache/CacheService.java
@@ -24,6 +24,7 @@
 import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
+import android.database.MergeCursor;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
@@ -53,1026 +54,1153 @@
 import com.cooliris.media.Utils;
 
 public final class CacheService extends IntentService {
-    public static final String ACTION_CACHE = "com.cooliris.cache.action.CACHE";
-    public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");
+	public static final String ACTION_CACHE = "com.cooliris.cache.action.CACHE";
+	public static final DiskCache sAlbumCache = new DiskCache("local-album-cache");
+	public static final DiskCache sMetaAlbumCache = new DiskCache("local-meta-album-cache");
 
-    private static final String TAG = "CacheService";
-    private static ImageList sList = null;
+	private static final String TAG = "CacheService";
+	private static ImageList sList = null;
 
-    // Wait 2 seconds to start the thumbnailer so that the application can load without any overheads.
-    private static final int THUMBNAILER_WAIT_IN_MS = 2000;
-    private static final int DEFAULT_THUMBNAIL_WIDTH = 128;
-    private static final int DEFAULT_THUMBNAIL_HEIGHT = 96;
+	// Wait 2 seconds to start the thumbnailer so that the application can load
+	// without any overheads.
+	private static final int THUMBNAILER_WAIT_IN_MS = 2000;
+	private static final int DEFAULT_THUMBNAIL_WIDTH = 128;
+	private static final int DEFAULT_THUMBNAIL_HEIGHT = 96;
 
-    public static final String DEFAULT_IMAGE_SORT_ORDER = Images.ImageColumns.DATE_TAKEN + " ASC, "
-            + Images.ImageColumns.DATE_ADDED + " ASC";
-    public static final String DEFAULT_VIDEO_SORT_ORDER = Video.VideoColumns.DATE_TAKEN + " ASC, " + Video.VideoColumns.DATE_ADDED
-            + " ASC";
-    public static final String DEFAULT_BUCKET_SORT_ORDER = "upper(" + Images.ImageColumns.BUCKET_DISPLAY_NAME + ") ASC";
+	public static final String DEFAULT_IMAGE_SORT_ORDER = Images.ImageColumns.DATE_TAKEN + " ASC, "
+	        + Images.ImageColumns.DATE_ADDED + " ASC";
+	public static final String DEFAULT_VIDEO_SORT_ORDER = Video.VideoColumns.DATE_TAKEN + " ASC, " + Video.VideoColumns.DATE_ADDED
+	        + " ASC";
+	public static final String DEFAULT_BUCKET_SORT_ORDER = "upper(" + Images.ImageColumns.BUCKET_DISPLAY_NAME + ") ASC";
 
-    // Must preserve order between these indices and the order of the terms in BUCKET_PROJECTION_IMAGES, BUCKET_PROJECTION_VIDEOS.
-    // Not using SortedHashMap for efficieny reasons.
-    public static final int BUCKET_ID_INDEX = 0;
-    public static final int BUCKET_NAME_INDEX = 1;
-    public static final String[] BUCKET_PROJECTION_IMAGES = new String[] { Images.ImageColumns.BUCKET_ID,
-            Images.ImageColumns.BUCKET_DISPLAY_NAME };
+	// Must preserve order between these indices and the order of the terms in
+	// BUCKET_PROJECTION_IMAGES, BUCKET_PROJECTION_VIDEOS.
+	// Not using SortedHashMap for efficieny reasons.
+	public static final int BUCKET_ID_INDEX = 0;
+	public static final int BUCKET_NAME_INDEX = 1;
+	public static final String[] BUCKET_PROJECTION_IMAGES = new String[] { Images.ImageColumns.BUCKET_ID,
+	        Images.ImageColumns.BUCKET_DISPLAY_NAME };
 
-    public static final String[] BUCKET_PROJECTION_VIDEOS = new String[] { Video.VideoColumns.BUCKET_ID,
-            Video.VideoColumns.BUCKET_DISPLAY_NAME };
+	public static final String[] BUCKET_PROJECTION_VIDEOS = new String[] { Video.VideoColumns.BUCKET_ID,
+	        Video.VideoColumns.BUCKET_DISPLAY_NAME };
 
-    // Must preserve order between these indices and the order of the terms in THUMBNAIL_PROJECTION.
-    public static final int THUMBNAIL_ID_INDEX = 0;
-    public static final int THUMBNAIL_DATE_MODIFIED_INDEX = 1;
-    public static final int THUMBNAIL_DATA_INDEX = 2;
-    public static final int THUMBNAIL_ORIENTATION_INDEX = 2;
-    public static final String[] THUMBNAIL_PROJECTION = new String[] { Images.ImageColumns._ID, Images.ImageColumns.DATE_MODIFIED,
-            Images.ImageColumns.DATA, Images.ImageColumns.ORIENTATION };
+	// Must preserve order between these indices and the order of the terms in
+	// THUMBNAIL_PROJECTION.
+	public static final int THUMBNAIL_ID_INDEX = 0;
+	public static final int THUMBNAIL_DATE_MODIFIED_INDEX = 1;
+	public static final int THUMBNAIL_DATA_INDEX = 2;
+	public static final int THUMBNAIL_ORIENTATION_INDEX = 2;
+	public static final String[] THUMBNAIL_PROJECTION = new String[] { Images.ImageColumns._ID, Images.ImageColumns.DATE_MODIFIED,
+	        Images.ImageColumns.DATA, Images.ImageColumns.ORIENTATION };
 
-    // Must preserve order between these indices and the order of the terms in INITIAL_PROJECTION_IMAGES and
-    // INITIAL_PROJECTION_VIDEOS.
-    public static final int MEDIA_ID_INDEX = 0;
-    public static final int MEDIA_CAPTION_INDEX = 1;
-    public static final int MEDIA_MIME_TYPE_INDEX = 2;
-    public static final int MEDIA_LATITUDE_INDEX = 3;
-    public static final int MEDIA_LONGITUDE_INDEX = 4;
-    public static final int MEDIA_DATE_TAKEN_INDEX = 5;
-    public static final int MEDIA_DATE_ADDED_INDEX = 6;
-    public static final int MEDIA_DATE_MODIFIED_INDEX = 7;
-    public static final int MEDIA_DATA_INDEX = 8;
-    public static final int MEDIA_ORIENTATION_OR_DURATION_INDEX = 9;
-    public static final int MEDIA_BUCKET_ID_INDEX = 10;
-    public static final String[] PROJECTION_IMAGES = new String[] { Images.ImageColumns._ID, Images.ImageColumns.TITLE,
-            Images.ImageColumns.MIME_TYPE, Images.ImageColumns.LATITUDE, Images.ImageColumns.LONGITUDE,
-            Images.ImageColumns.DATE_TAKEN, Images.ImageColumns.DATE_ADDED, Images.ImageColumns.DATE_MODIFIED,
-            Images.ImageColumns.DATA, Images.ImageColumns.ORIENTATION, Images.ImageColumns.BUCKET_ID };
+	public static final String[] SENSE_PROJECTION = new String[] { Images.ImageColumns.BUCKET_ID,
+	        "MAX(" + Images.ImageColumns.DATE_ADDED + ")" };
 
-    private static final String[] PROJECTION_VIDEOS = new String[] { Video.VideoColumns._ID, Video.VideoColumns.TITLE,
-            Video.VideoColumns.MIME_TYPE, Video.VideoColumns.LATITUDE, Video.VideoColumns.LONGITUDE, Video.VideoColumns.DATE_TAKEN,
-            Video.VideoColumns.DATE_ADDED, Video.VideoColumns.DATE_MODIFIED, Video.VideoColumns.DATA, Video.VideoColumns.DURATION,
-            Video.VideoColumns.BUCKET_ID };
+	// Must preserve order between these indices and the order of the terms in
+	// INITIAL_PROJECTION_IMAGES and
+	// INITIAL_PROJECTION_VIDEOS.
+	public static final int MEDIA_ID_INDEX = 0;
+	public static final int MEDIA_CAPTION_INDEX = 1;
+	public static final int MEDIA_MIME_TYPE_INDEX = 2;
+	public static final int MEDIA_LATITUDE_INDEX = 3;
+	public static final int MEDIA_LONGITUDE_INDEX = 4;
+	public static final int MEDIA_DATE_TAKEN_INDEX = 5;
+	public static final int MEDIA_DATE_ADDED_INDEX = 6;
+	public static final int MEDIA_DATE_MODIFIED_INDEX = 7;
+	public static final int MEDIA_DATA_INDEX = 8;
+	public static final int MEDIA_ORIENTATION_OR_DURATION_INDEX = 9;
+	public static final int MEDIA_BUCKET_ID_INDEX = 10;
+	public static final String[] PROJECTION_IMAGES = new String[] { Images.ImageColumns._ID, Images.ImageColumns.TITLE,
+	        Images.ImageColumns.MIME_TYPE, Images.ImageColumns.LATITUDE, Images.ImageColumns.LONGITUDE,
+	        Images.ImageColumns.DATE_TAKEN, Images.ImageColumns.DATE_ADDED, Images.ImageColumns.DATE_MODIFIED,
+	        Images.ImageColumns.DATA, Images.ImageColumns.ORIENTATION, Images.ImageColumns.BUCKET_ID };
 
-    public static final String BASE_CONTENT_STRING_IMAGES = (Images.Media.EXTERNAL_CONTENT_URI).toString() + "/";
-    public static final String BASE_CONTENT_STRING_VIDEOS = (Video.Media.EXTERNAL_CONTENT_URI).toString() + "/";
-    private static final AtomicReference<Thread> CACHE_THREAD = new AtomicReference<Thread>();
-    private static final AtomicReference<Thread> THUMBNAIL_THREAD = new AtomicReference<Thread>();
+	private static final String[] PROJECTION_VIDEOS = new String[] { Video.VideoColumns._ID, Video.VideoColumns.TITLE,
+	        Video.VideoColumns.MIME_TYPE, Video.VideoColumns.LATITUDE, Video.VideoColumns.LONGITUDE, Video.VideoColumns.DATE_TAKEN,
+	        Video.VideoColumns.DATE_ADDED, Video.VideoColumns.DATE_MODIFIED, Video.VideoColumns.DATA, Video.VideoColumns.DURATION,
+	        Video.VideoColumns.BUCKET_ID };
 
-    // Special indices in the Albumcache.
-    private static final int ALBUM_CACHE_METADATA_INDEX = -1;
-    private static final int ALBUM_CACHE_DIRTY_INDEX = -2;
-    private static final int ALBUM_CACHE_INCOMPLETE_INDEX = -3;
-    private static final int ALBUM_CACHE_DIRTY_BUCKET_INDEX = -4;
-    private static final int ALBUM_CACHE_LOCALE_INDEX = -5;
+	public static final String BASE_CONTENT_STRING_IMAGES = (Images.Media.EXTERNAL_CONTENT_URI).toString() + "/";
+	public static final String BASE_CONTENT_STRING_VIDEOS = (Video.Media.EXTERNAL_CONTENT_URI).toString() + "/";
+	private static final AtomicReference<Thread> CACHE_THREAD = new AtomicReference<Thread>();
+	private static final AtomicReference<Thread> THUMBNAIL_THREAD = new AtomicReference<Thread>();
 
-    private static final DateFormat mDateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
-    private static final DateFormat mAltDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
-    private static final byte[] sDummyData = new byte[] { 1 };
-    private static boolean QUEUE_DIRTY_SET;
-    private static boolean QUEUE_DIRTY_ALL;
+	// Special indices in the Albumcache.
+	private static final int ALBUM_CACHE_METADATA_INDEX = -1;
+	private static final int ALBUM_CACHE_DIRTY_INDEX = -2;
+	private static final int ALBUM_CACHE_INCOMPLETE_INDEX = -3;
+	private static final int ALBUM_CACHE_DIRTY_BUCKET_INDEX = -4;
+	private static final int ALBUM_CACHE_LOCALE_INDEX = -5;
 
-    public static final String getCachePath(final String subFolderName) {
-        return Environment.getExternalStorageDirectory() + "/Android/data/com.cooliris.media/cache/" + subFolderName;
-    }
+	private static final DateFormat mDateFormat = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss");
+	private static final DateFormat mAltDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
+	private static final byte[] sDummyData = new byte[] { 1 };
+	private static boolean QUEUE_DIRTY_SET;
+	private static boolean QUEUE_DIRTY_ALL;
+	private static boolean QUEUE_DIRTY_SENSE;
 
-    public static final void startCache(final Context context, final boolean checkthumbnails) {
-        final Locale locale = getLocaleForAlbumCache();
-        final Locale defaultLocale = Locale.getDefault();
-        if (locale == null || !locale.equals(defaultLocale)) {
-            sAlbumCache.deleteAll();
-            putLocaleForAlbumCache(defaultLocale);
-        }
-        final Intent intent = new Intent(ACTION_CACHE, null, context, CacheService.class);
-        intent.putExtra("checkthumbnails", checkthumbnails);
-        context.startService(intent);
-    }
+	public interface Observer {
+		void onChange(long[] bucketIds);
+	}
 
-    public static final boolean isCacheReady(final boolean onlyMediaSets) {
-        if (onlyMediaSets) {
-            return (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null);
-        } else {
-            return (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null && sAlbumCache
-                    .get(ALBUM_CACHE_INCOMPLETE_INDEX, 0) == null);
-        }
-    }
+	public static final String getCachePath(final String subFolderName) {
+		return Environment.getExternalStorageDirectory() + "/Android/data/com.cooliris.media/cache/" + subFolderName;
+	}
 
-    public static final boolean isCacheReady(final long setId) {
-        final boolean isReady = (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null
-                && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null && sAlbumCache.get(ALBUM_CACHE_INCOMPLETE_INDEX, 0) == null);
-        if (!isReady) {
-            return isReady;
-        }
-        // Also, we need to check if this setId is dirty.
-        final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
-        if (existingData != null && existingData.length > 0) {
-            final long[] ids = toLongArray(existingData);
-            final int numIds = ids.length;
-            for (int i = 0; i < numIds; ++i) {
-                if (ids[i] == setId) {
-                    return false;
-                }
-            }
-        }
-        return true;
-    }
+	public static final void startCache(final Context context, final boolean checkthumbnails) {
+		final Locale locale = getLocaleForAlbumCache();
+		final Locale defaultLocale = Locale.getDefault();
+		if (locale == null || !locale.equals(defaultLocale)) {
+			sAlbumCache.deleteAll();
+			putLocaleForAlbumCache(defaultLocale);
+		}
+		final Intent intent = new Intent(ACTION_CACHE, null, context, CacheService.class);
+		intent.putExtra("checkthumbnails", checkthumbnails);
+		context.startService(intent);
+	}
 
-    public static final boolean isPresentInCache(final long setId) {
-        return sAlbumCache.get(setId, 0) != null;
-    }
+	public static final boolean isCacheReady(final boolean onlyMediaSets) {
+		if (onlyMediaSets) {
+			return (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null);
+		} else {
+			return (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null && sAlbumCache
+			        .get(ALBUM_CACHE_INCOMPLETE_INDEX, 0) == null);
+		}
+	}
 
-    public static final void markDirty(final Context context) {
-        sList = null;
-        sAlbumCache.put(ALBUM_CACHE_DIRTY_INDEX, sDummyData);
-        if (CACHE_THREAD.get() == null) {
-            restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
-                public void run() {
-                    refresh(context);
-                }
-            });
-        } else {
-            QUEUE_DIRTY_ALL = true;
-        }
-    }
+	public static final boolean isCacheReady(final long setId) {
+		final boolean isReady = (sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0) != null
+		        && sAlbumCache.get(ALBUM_CACHE_DIRTY_INDEX, 0) == null && sAlbumCache.get(ALBUM_CACHE_INCOMPLETE_INDEX, 0) == null);
+		if (!isReady) {
+			return isReady;
+		}
+		// Also, we need to check if this setId is dirty.
+		final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
+		if (existingData != null && existingData.length > 0) {
+			final long[] ids = toLongArray(existingData);
+			final int numIds = ids.length;
+			for (int i = 0; i < numIds; ++i) {
+				if (ids[i] == setId) {
+					return false;
+				}
+			}
+		}
+		return true;
+	}
 
-    public static final void markDirtyImmediate(final long id) {
-        sList = null;
-        byte[] data = longToByteArray(id);
-        final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
-        if (existingData != null && existingData.length > 0) {
-            final long[] ids = toLongArray(existingData);
-            final int numIds = ids.length;
-            for (int i = 0; i < numIds; ++i) {
-                if (ids[i] == id) {
-                    return;
-                }
-            }
-            // Add this to the existing keys and concatenate the byte arrays.
-            data = concat(data, existingData);
-        }
-        sAlbumCache.put(ALBUM_CACHE_DIRTY_BUCKET_INDEX, data);
-    }
+	public static final boolean isPresentInCache(final long setId) {
+		return sAlbumCache.get(setId, 0) != null;
+	}
 
-    public static final void markDirty(final Context context, final long id) {
-        markDirtyImmediate(id);
-        if (CACHE_THREAD.get() == null) {
-            restartThread(CACHE_THREAD, "CacheRefreshDirtySets", new Runnable() {
-                public void run() {
-                    refreshDirtySets(context);
-                }
-            });
-        } else {
-            QUEUE_DIRTY_SET = true;
-        }
-    }
+	public static final void senseDirty(final Context context, final Observer observer) {
+		if (CACHE_THREAD.get() == null) {
+			QUEUE_DIRTY_SENSE = false;
+			QUEUE_DIRTY_ALL = false;
+			QUEUE_DIRTY_SET = false;
+			restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
+				public void run() {
+					Log.i(TAG, "Computing dirty sets.");
+					long ids[] = computeDirtySets(context);
+					if (ids != null && observer != null) {
+						observer.onChange(ids);
+					}
+					if (ids.length > 0) {
+						sList = null;
+					}
+					Log.i(TAG, "Done computing dirty sets for num " + ids.length);
+				}
+			});
+		} else {
+			QUEUE_DIRTY_SENSE = true;
+		}
+	}
 
-    public static final boolean setHasItems(final ContentResolver cr, final long setId) {
-        final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
-        final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
-        final StringBuffer whereString = new StringBuffer(Images.ImageColumns.BUCKET_ID + "=" + setId);
-        final Cursor cursorImages = cr.query(uriImages, BUCKET_PROJECTION_IMAGES, whereString.toString(), null, null);
-        if (cursorImages != null && cursorImages.getCount() > 0) {
-            cursorImages.close();
-            return true;
-        }
-        final Cursor cursorVideos = cr.query(uriVideos, BUCKET_PROJECTION_VIDEOS, whereString.toString(), null, null);
-        if (cursorVideos != null && cursorVideos.getCount() > 0) {
-            cursorVideos.close();
-            return true;
-        }
-        return false;
-    }
+	public static final void markDirty(final Context context) {
+		sList = null;
+		sAlbumCache.put(ALBUM_CACHE_DIRTY_INDEX, sDummyData);
+		if (CACHE_THREAD.get() == null) {
+			QUEUE_DIRTY_SENSE = false;
+			QUEUE_DIRTY_ALL = false;
+			QUEUE_DIRTY_SET = false;
+			restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
+				public void run() {
+					refresh(context);
+				}
+			});
+		} else {
+			QUEUE_DIRTY_ALL = true;
+		}
+	}
 
-    public static final void loadMediaSets(final MediaFeed feed, final DataSource source, final boolean includeImages,
-            final boolean includeVideos) {
-        int timeElapsed = 0;
-        while (!isCacheReady(true) && timeElapsed < 10000) {
-            try {
-                Thread.sleep(300);
-            } catch (InterruptedException e) {
-                return;
-            }
-            timeElapsed += 300;
-        }
-        final byte[] albumData = sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0);
-        if (albumData != null && albumData.length > 0) {
-            final DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
-            try {
-                final int numAlbums = dis.readInt();
-                Log.i(TAG, "Loading " + numAlbums + " albums.");
-                for (int i = 0; i < numAlbums; ++i) {
-                    final long setId = dis.readLong();
-                    final String name = Utils.readUTF(dis);
-                    final boolean hasImages = dis.readBoolean();
-                    final boolean hasVideos = dis.readBoolean();
-                    MediaSet mediaSet = feed.getMediaSet(setId);
-                    if (mediaSet == null) {
-                        mediaSet = feed.addMediaSet(setId, source);
-                    }
-                    if ((includeImages && hasImages) || (includeVideos && hasVideos)) {
-                        mediaSet.mName = name;
-                        mediaSet.mHasImages = hasImages;
-                        mediaSet.mHasVideos = hasVideos;
-                        mediaSet.mPicasaAlbumId = Shared.INVALID;
-                        mediaSet.generateTitle(true);
-                    }
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "Error loading albums.");
-                sAlbumCache.deleteAll();
-                putLocaleForAlbumCache(Locale.getDefault());
-            }
-        } else {
-            Log.d(TAG, "No albums found.");
-        }
-    }
+	public static final void markDirtyImmediate(final long id) {
+		if (id == Shared.INVALID) {
+			return;
+		}
+		sList = null;
+		byte[] data = longToByteArray(id);
+		final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
+		if (existingData != null && existingData.length > 0) {
+			final long[] ids = toLongArray(existingData);
+			final int numIds = ids.length;
+			for (int i = 0; i < numIds; ++i) {
+				if (ids[i] == id) {
+					return;
+				}
+			}
+			// Add this to the existing keys and concatenate the byte arrays.
+			data = concat(data, existingData);
+		}
+		sAlbumCache.put(ALBUM_CACHE_DIRTY_BUCKET_INDEX, data);
+	}
 
-    public static final void loadMediaSet(final MediaFeed feed, final DataSource source, final long bucketId) {
-        int timeElapsed = 0;
-        while (!isCacheReady(false) && timeElapsed < 10000) {
-            try {
-                Thread.sleep(300);
-            } catch (InterruptedException e) {
-                return;
-            }
-            timeElapsed += 300;
-        }
-        final byte[] albumData = sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0);
-        if (albumData != null && albumData.length > 0) {
-            DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
-            try {
-                final int numAlbums = dis.readInt();
-                for (int i = 0; i < numAlbums; ++i) {
-                    final long setId = dis.readLong();
-                    MediaSet mediaSet = null;
-                    if (setId == bucketId) {
-                        mediaSet = feed.getMediaSet(setId);
-                        if (mediaSet == null) {
-                            mediaSet = feed.addMediaSet(setId, source);
-                        }
-                    } else {
-                        mediaSet = new MediaSet();
-                    }
-                    mediaSet.mName = Utils.readUTF(dis);
-                    if (setId == bucketId) {
-                        mediaSet.mPicasaAlbumId = Shared.INVALID;
-                        mediaSet.generateTitle(true);
-                        return;
-                    }
-                }
-            } catch (IOException e) {
-                Log.e(TAG, "Error finding album " + bucketId);
-                sAlbumCache.deleteAll();
-                putLocaleForAlbumCache(Locale.getDefault());
-            }
-        } else {
-            Log.d(TAG, "No album found for album id " + bucketId);
-        }
-    }
+	public static final void markDirty(final Context context, final long id) {
+		markDirtyImmediate(id);
+		if (CACHE_THREAD.get() == null) {
+			QUEUE_DIRTY_SET = false;
+			restartThread(CACHE_THREAD, "CacheRefreshDirtySets", new Runnable() {
+				public void run() {
+					refreshDirtySets(context);
+				}
+			});
+		} else {
+			QUEUE_DIRTY_SET = true;
+		}
+	}
 
-    public static final void loadMediaItemsIntoMediaFeed(final MediaFeed feed, final MediaSet set, final int rangeStart,
-            final int rangeEnd, final boolean includeImages, final boolean includeVideos) {
-        int timeElapsed = 0;
-        byte[] albumData = null;
-        while (!isCacheReady(set.mId) && timeElapsed < 30000) {
-            try {
-                Thread.sleep(300);
-            } catch (InterruptedException e) {
-                return;
-            }
-            timeElapsed += 300;
-        }
-        albumData = sAlbumCache.get(set.mId, 0);
-        if (albumData != null && set.mNumItemsLoaded < set.getNumExpectedItems()) {
-            final DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
-            try {
-                final int numItems = dis.readInt();
-                Log.i(TAG, "Loading Set Id " + set.mId + " with " + numItems + " items.");
-                set.setNumExpectedItems(numItems);
-                set.mMinTimestamp = dis.readLong();
-                set.mMaxTimestamp = dis.readLong();
-                for (int i = 0; i < numItems; ++i) {
-                    final MediaItem item = new MediaItem();
-                    // Must preserve order with method that writes to cache.
-                    item.mId = dis.readLong();
-                    item.mCaption = Utils.readUTF(dis);
-                    item.mMimeType = Utils.readUTF(dis);
-                    item.setMediaType(dis.readInt());
-                    item.mLatitude = dis.readDouble();
-                    item.mLongitude = dis.readDouble();
-                    item.mDateTakenInMs = dis.readLong();
-                    item.mTriedRetrievingExifDateTaken = dis.readBoolean();
-                    item.mDateAddedInSec = dis.readLong();
-                    item.mDateModifiedInSec = dis.readLong();
-                    item.mDurationInSec = dis.readInt();
-                    item.mRotation = (float) dis.readInt();
-                    item.mFilePath = Utils.readUTF(dis);
-                    int itemMediaType = item.getMediaType();
-                    if ((itemMediaType == MediaItem.MEDIA_TYPE_IMAGE && includeImages)
-                            || (itemMediaType == MediaItem.MEDIA_TYPE_VIDEO && includeVideos)) {
-                        String baseUri = (itemMediaType == MediaItem.MEDIA_TYPE_IMAGE) ? BASE_CONTENT_STRING_IMAGES
-                                : BASE_CONTENT_STRING_VIDEOS;
-                        item.mContentUri = baseUri + item.mId;
-                        feed.addItemToMediaSet(item, set);
-                    }
-                }
-                dis.close();
-            } catch (IOException e) {
-                Log.e(TAG, "Error loading items for album " + set.mName);
-                sAlbumCache.deleteAll();
-                putLocaleForAlbumCache(Locale.getDefault());
-            }
-        } else {
-            Log.d(TAG, "No items found for album " + set.mName);
-        }
-        set.updateNumExpectedItems();
-        set.generateTitle(true);
-    }
+	public static final boolean setHasItems(final ContentResolver cr, final long setId) {
+		final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
+		final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
+		final StringBuffer whereString = new StringBuffer(Images.ImageColumns.BUCKET_ID + "=" + setId);
+		final Cursor cursorImages = cr.query(uriImages, BUCKET_PROJECTION_IMAGES, whereString.toString(), null, null);
+		if (cursorImages != null && cursorImages.getCount() > 0) {
+			cursorImages.close();
+			return true;
+		}
+		final Cursor cursorVideos = cr.query(uriVideos, BUCKET_PROJECTION_VIDEOS, whereString.toString(), null, null);
+		if (cursorVideos != null && cursorVideos.getCount() > 0) {
+			cursorVideos.close();
+			return true;
+		}
+		return false;
+	}
 
-    public static final void populateVideoItemFromCursor(final MediaItem item, final ContentResolver cr, final Cursor cursor,
-            final String baseUri) {
-        item.setMediaType(MediaItem.MEDIA_TYPE_VIDEO);
-        populateMediaItemFromCursor(item, cr, cursor, baseUri);
-    }
+	public static final void loadMediaSets(final MediaFeed feed, final DataSource source, final boolean includeImages,
+	        final boolean includeVideos) {
+		int timeElapsed = 0;
+		while (!isCacheReady(true) && timeElapsed < 10000) {
+			try {
+				Thread.sleep(300);
+			} catch (InterruptedException e) {
+				return;
+			}
+			timeElapsed += 300;
+		}
+		final byte[] albumData = sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0);
+		if (albumData != null && albumData.length > 0) {
+			final DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
+			try {
+				final int numAlbums = dis.readInt();
+				for (int i = 0; i < numAlbums; ++i) {
+					final long setId = dis.readLong();
+					final String name = Utils.readUTF(dis);
+					final boolean hasImages = dis.readBoolean();
+					final boolean hasVideos = dis.readBoolean();
+					MediaSet mediaSet = feed.getMediaSet(setId);
+					if (mediaSet == null) {
+						mediaSet = feed.addMediaSet(setId, source);
+					}
+					if ((includeImages && hasImages) || (includeVideos && hasVideos)) {
+						mediaSet.mName = name;
+						mediaSet.mHasImages = hasImages;
+						mediaSet.mHasVideos = hasVideos;
+						mediaSet.mPicasaAlbumId = Shared.INVALID;
+						mediaSet.generateTitle(true);
+					}
+				}
+			} catch (IOException e) {
+				Log.e(TAG, "Error loading albums.");
+				sAlbumCache.deleteAll();
+				putLocaleForAlbumCache(Locale.getDefault());
+			}
+		} else {
+			Log.d(TAG, "No albums found.");
+		}
+	}
 
-    public static final void populateMediaItemFromCursor(final MediaItem item, final ContentResolver cr, final Cursor cursor,
-            final String baseUri) {
-        item.mId = cursor.getLong(CacheService.MEDIA_ID_INDEX);
-        // item.mCaption = cursor.getString(CacheService.MEDIA_CAPTION_INDEX);
-        item.mMimeType = cursor.getString(CacheService.MEDIA_MIME_TYPE_INDEX);
-        item.mLatitude = cursor.getDouble(CacheService.MEDIA_LATITUDE_INDEX);
-        item.mLongitude = cursor.getDouble(CacheService.MEDIA_LONGITUDE_INDEX);
-        item.mDateTakenInMs = cursor.getLong(CacheService.MEDIA_DATE_TAKEN_INDEX);
-        item.mDateAddedInSec = cursor.getLong(CacheService.MEDIA_DATE_ADDED_INDEX);
-        item.mDateModifiedInSec = cursor.getLong(CacheService.MEDIA_DATE_MODIFIED_INDEX);
-        if (item.mDateTakenInMs == item.mDateModifiedInSec) {
-            item.mDateTakenInMs = item.mDateModifiedInSec * 1000;
-        }
-        item.mFilePath = cursor.getString(CacheService.MEDIA_DATA_INDEX);
-        if (baseUri != null)
-            item.mContentUri = baseUri + item.mId;
-        final int itemMediaType = item.getMediaType();
-        // Check to see if a new date taken is available.
-        final long dateTaken = fetchDateTaken(item);
-        if (dateTaken != -1L && item.mContentUri != null) {
-            item.mDateTakenInMs = dateTaken;
-            final ContentValues values = new ContentValues();
-            if (itemMediaType == MediaItem.MEDIA_TYPE_VIDEO) {
-                values.put(Video.VideoColumns.DATE_TAKEN, item.mDateTakenInMs);
-            } else {
-                values.put(Images.ImageColumns.DATE_TAKEN, item.mDateTakenInMs);
-            }
-            cr.update(Uri.parse(item.mContentUri), values, null, null);
-        }
+	public static final void loadMediaSet(final MediaFeed feed, final DataSource source, final long bucketId) {
+		int timeElapsed = 0;
+		while (!isCacheReady(false) && timeElapsed < 10000) {
+			try {
+				Thread.sleep(300);
+			} catch (InterruptedException e) {
+				return;
+			}
+			timeElapsed += 300;
+		}
+		final byte[] albumData = sAlbumCache.get(ALBUM_CACHE_METADATA_INDEX, 0);
+		if (albumData != null && albumData.length > 0) {
+			DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
+			try {
+				final int numAlbums = dis.readInt();
+				for (int i = 0; i < numAlbums; ++i) {
+					final long setId = dis.readLong();
+					MediaSet mediaSet = null;
+					if (setId == bucketId) {
+						mediaSet = feed.getMediaSet(setId);
+						if (mediaSet == null) {
+							mediaSet = feed.addMediaSet(setId, source);
+						}
+					} else {
+						mediaSet = new MediaSet();
+					}
+					mediaSet.mName = Utils.readUTF(dis);
+					if (setId == bucketId) {
+						mediaSet.mPicasaAlbumId = Shared.INVALID;
+						mediaSet.generateTitle(true);
+						return;
+					}
+				}
+			} catch (IOException e) {
+				Log.e(TAG, "Error finding album " + bucketId);
+				sAlbumCache.deleteAll();
+				putLocaleForAlbumCache(Locale.getDefault());
+			}
+		} else {
+			Log.d(TAG, "No album found for album id " + bucketId);
+		}
+	}
 
-        final int orientationDurationValue = cursor.getInt(CacheService.MEDIA_ORIENTATION_OR_DURATION_INDEX);
-        if (itemMediaType == MediaItem.MEDIA_TYPE_IMAGE) {
-            item.mRotation = orientationDurationValue;
-        } else {
-            item.mDurationInSec = orientationDurationValue;
-        }
-    }
+	public static final void loadMediaItemsIntoMediaFeed(final MediaFeed feed, final MediaSet set, final int rangeStart,
+	        final int rangeEnd, final boolean includeImages, final boolean includeVideos) {
+		int timeElapsed = 0;
+		byte[] albumData = null;
+		while (!isCacheReady(set.mId) && timeElapsed < 30000) {
+			try {
+				Thread.sleep(300);
+			} catch (InterruptedException e) {
+				return;
+			}
+			timeElapsed += 300;
+		}
+		albumData = sAlbumCache.get(set.mId, 0);
+		if (albumData != null && set.mNumItemsLoaded < set.getNumExpectedItems()) {
+			final DataInputStream dis = new DataInputStream(new BufferedInputStream(new ByteArrayInputStream(albumData), 256));
+			try {
+				final int numItems = dis.readInt();
+				set.setNumExpectedItems(numItems);
+				set.mMinTimestamp = dis.readLong();
+				set.mMaxTimestamp = dis.readLong();
+				for (int i = 0; i < numItems; ++i) {
+					final MediaItem item = new MediaItem();
+					// Must preserve order with method that writes to cache.
+					item.mId = dis.readLong();
+					item.mCaption = Utils.readUTF(dis);
+					item.mMimeType = Utils.readUTF(dis);
+					item.setMediaType(dis.readInt());
+					item.mLatitude = dis.readDouble();
+					item.mLongitude = dis.readDouble();
+					item.mDateTakenInMs = dis.readLong();
+					item.mTriedRetrievingExifDateTaken = dis.readBoolean();
+					item.mDateAddedInSec = dis.readLong();
+					item.mDateModifiedInSec = dis.readLong();
+					item.mDurationInSec = dis.readInt();
+					item.mRotation = (float) dis.readInt();
+					item.mFilePath = Utils.readUTF(dis);
+					int itemMediaType = item.getMediaType();
+					if ((itemMediaType == MediaItem.MEDIA_TYPE_IMAGE && includeImages)
+					        || (itemMediaType == MediaItem.MEDIA_TYPE_VIDEO && includeVideos)) {
+						String baseUri = (itemMediaType == MediaItem.MEDIA_TYPE_IMAGE) ? BASE_CONTENT_STRING_IMAGES
+						        : BASE_CONTENT_STRING_VIDEOS;
+						item.mContentUri = baseUri + item.mId;
+						feed.addItemToMediaSet(item, set);
+					}
+				}
+				dis.close();
+			} catch (IOException e) {
+				Log.e(TAG, "Error loading items for album " + set.mName);
+				sAlbumCache.deleteAll();
+				putLocaleForAlbumCache(Locale.getDefault());
+			}
+		} else {
+			Log.d(TAG, "No items found for album " + set.mName);
+		}
+		set.updateNumExpectedItems();
+		set.generateTitle(true);
+	}
 
-    // Returns -1 if we failed to examine EXIF information or EXIF parsing failed.
-    public static final long fetchDateTaken(final MediaItem item) {
-        if (!item.isDateTakenValid() && !item.mTriedRetrievingExifDateTaken
-                && (item.mFilePath.endsWith(".jpg") || item.mFilePath.endsWith(".jpeg"))) {
-            try {
-                Log.i(TAG, "Parsing date taken from exif");
-                final ExifInterface exif = new ExifInterface(item.mFilePath);
-                final String dateTakenStr = exif.getAttribute(ExifInterface.TAG_DATETIME);
-                if (dateTakenStr != null) {
-                    try {
-                        final Date dateTaken = mDateFormat.parse(dateTakenStr);
-                        return dateTaken.getTime();
-                    } catch (ParseException pe) {
-                        try {
-                            final Date dateTaken = mAltDateFormat.parse(dateTakenStr);
-                            return dateTaken.getTime();
-                        } catch (ParseException pe2) {
-                            Log.i(TAG, "Unable to parse date out of string - " + dateTakenStr);
-                        }
-                    }
-                }
-            } catch (Exception e) {
-                Log.i(TAG, "Error reading Exif information, probably not a jpeg.");
-            }
+	public static final void populateVideoItemFromCursor(final MediaItem item, final ContentResolver cr, final Cursor cursor,
+	        final String baseUri) {
+		item.setMediaType(MediaItem.MEDIA_TYPE_VIDEO);
+		populateMediaItemFromCursor(item, cr, cursor, baseUri);
+	}
 
-            // Ensures that we only try retrieving EXIF date taken once.
-            item.mTriedRetrievingExifDateTaken = true;
-        }
-        return -1L;
-    }
+	public static final void populateMediaItemFromCursor(final MediaItem item, final ContentResolver cr, final Cursor cursor,
+	        final String baseUri) {
+		item.mId = cursor.getLong(CacheService.MEDIA_ID_INDEX);
+		item.mCaption = cursor.getString(CacheService.MEDIA_CAPTION_INDEX);
+		item.mMimeType = cursor.getString(CacheService.MEDIA_MIME_TYPE_INDEX);
+		item.mLatitude = cursor.getDouble(CacheService.MEDIA_LATITUDE_INDEX);
+		item.mLongitude = cursor.getDouble(CacheService.MEDIA_LONGITUDE_INDEX);
+		item.mDateTakenInMs = cursor.getLong(CacheService.MEDIA_DATE_TAKEN_INDEX);
+		item.mDateAddedInSec = cursor.getLong(CacheService.MEDIA_DATE_ADDED_INDEX);
+		item.mDateModifiedInSec = cursor.getLong(CacheService.MEDIA_DATE_MODIFIED_INDEX);
+		if (item.mDateTakenInMs == item.mDateModifiedInSec) {
+			item.mDateTakenInMs = item.mDateModifiedInSec * 1000;
+		}
+		item.mFilePath = cursor.getString(CacheService.MEDIA_DATA_INDEX);
+		if (baseUri != null)
+			item.mContentUri = baseUri + item.mId;
+		final int itemMediaType = item.getMediaType();
+		// Check to see if a new date taken is available.
+		final long dateTaken = fetchDateTaken(item);
+		if (dateTaken != -1L && item.mContentUri != null) {
+			item.mDateTakenInMs = dateTaken;
+			final ContentValues values = new ContentValues();
+			if (itemMediaType == MediaItem.MEDIA_TYPE_VIDEO) {
+				values.put(Video.VideoColumns.DATE_TAKEN, item.mDateTakenInMs);
+			} else {
+				values.put(Images.ImageColumns.DATE_TAKEN, item.mDateTakenInMs);
+			}
+			cr.update(Uri.parse(item.mContentUri), values, null, null);
+		}
 
-    public static final byte[] queryThumbnail(final Context context, final long thumbId, final long origId, final boolean isVideo,
-            final long timestamp) {
-        final DiskCache thumbnailCache = (isVideo) ? LocalDataSource.sThumbnailCacheVideo : LocalDataSource.sThumbnailCache;
-        return queryThumbnail(context, thumbId, origId, isVideo, thumbnailCache, timestamp);
-    }
+		final int orientationDurationValue = cursor.getInt(CacheService.MEDIA_ORIENTATION_OR_DURATION_INDEX);
+		if (itemMediaType == MediaItem.MEDIA_TYPE_IMAGE) {
+			item.mRotation = orientationDurationValue;
+		} else {
+			item.mDurationInSec = orientationDurationValue;
+		}
+	}
 
-    public static final ImageList getImageList(final Context context) {
-        if (sList != null)
-            return sList;
-        ImageList list = new ImageList();
-        final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
-        final ContentResolver cr = context.getContentResolver();
-        final Cursor cursorImages = cr.query(uriImages, THUMBNAIL_PROJECTION, null, null, null);
-        if (cursorImages != null && cursorImages.moveToFirst()) {
-            final int size = cursorImages.getCount();
-            final long[] ids = new long[size];
-            final long[] thumbnailIds = new long[size];
-            final long[] timestamp = new long[size];
-            final int[] orientation = new int[size];
-            int ctr = 0;
-            do {
-                if (Thread.interrupted()) {
-                    break;
-                }
-                ids[ctr] = cursorImages.getLong(THUMBNAIL_ID_INDEX);
-                timestamp[ctr] = cursorImages.getLong(THUMBNAIL_DATE_MODIFIED_INDEX);
-                thumbnailIds[ctr] = Utils.Crc64Long(cursorImages.getString(THUMBNAIL_DATA_INDEX));
-                orientation[ctr] = cursorImages.getInt(THUMBNAIL_ORIENTATION_INDEX);
-                ++ctr;
-            } while (cursorImages.moveToNext());
-            cursorImages.close();
-            list.ids = ids;
-            list.thumbids = thumbnailIds;
-            list.timestamp = timestamp;
-            list.orientation = orientation;
-        }
-        if (sList == null) {
-            sList = list;
-        }
-        return list;
-    }
+	// Returns -1 if we failed to examine EXIF information or EXIF parsing
+	// failed.
+	public static final long fetchDateTaken(final MediaItem item) {
+		if (!item.isDateTakenValid() && !item.mTriedRetrievingExifDateTaken
+		        && (item.mFilePath.endsWith(".jpg") || item.mFilePath.endsWith(".jpeg"))) {
+			try {
+				Log.i(TAG, "Parsing date taken from exif");
+				final ExifInterface exif = new ExifInterface(item.mFilePath);
+				final String dateTakenStr = exif.getAttribute(ExifInterface.TAG_DATETIME);
+				if (dateTakenStr != null) {
+					try {
+						final Date dateTaken = mDateFormat.parse(dateTakenStr);
+						return dateTaken.getTime();
+					} catch (ParseException pe) {
+						try {
+							final Date dateTaken = mAltDateFormat.parse(dateTakenStr);
+							return dateTaken.getTime();
+						} catch (ParseException pe2) {
+							Log.i(TAG, "Unable to parse date out of string - " + dateTakenStr);
+						}
+					}
+				}
+			} catch (Exception e) {
+				Log.i(TAG, "Error reading Exif information, probably not a jpeg.");
+			}
 
-    private static final byte[] queryThumbnail(final Context context, final long thumbId, final long origId, final boolean isVideo,
-            final DiskCache thumbnailCache, final long timestamp) {
-        if (!((Gallery) context).isPaused()) {
-            final Thread thumbnailThread = THUMBNAIL_THREAD.getAndSet(null);
-            if (thumbnailThread != null) {
-                thumbnailThread.interrupt();
-            }
-        }
-        byte[] bitmap = thumbnailCache.get(thumbId, timestamp);
-        if (bitmap == null) {
-            Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
-            final long time = SystemClock.uptimeMillis();
-            bitmap = buildThumbnailForId(context, thumbnailCache, thumbId, origId, isVideo, DEFAULT_THUMBNAIL_WIDTH,
-                    DEFAULT_THUMBNAIL_HEIGHT);
-            Log.i(TAG, "Built thumbnail and screennail for " + origId + " in " + (SystemClock.uptimeMillis() - time));
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-        }
-        return bitmap;
-    }
+			// Ensures that we only try retrieving EXIF date taken once.
+			item.mTriedRetrievingExifDateTaken = true;
+		}
+		return -1L;
+	}
 
-    private static final void buildThumbnails(final Context context) {
-        Log.i(TAG, "Preparing DiskCache for all thumbnails.");
-        ImageList list = getImageList(context);
-        final int size = (list.ids == null) ? 0 : list.ids.length;
-        final long[] ids = list.ids;
-        final long[] timestamp = list.timestamp;
-        final long[] thumbnailIds = list.thumbids;
-        final DiskCache thumbnailCache = LocalDataSource.sThumbnailCache;
-        for (int i = 0; i < size; ++i) {
-            if (Thread.interrupted()) {
-                return;
-            }
-            final long id = ids[i];
-            final long timeModifiedInSec = timestamp[i];
-            final long thumbnailId = thumbnailIds[i];
-            if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
-                buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
-                        DEFAULT_THUMBNAIL_HEIGHT);
-            }
-        }
-        Log.i(TAG, "DiskCache ready for all thumbnails.");
-    }
+	public static final byte[] queryThumbnail(final Context context, final long thumbId, final long origId, final boolean isVideo,
+	        final long timestamp) {
+		final DiskCache thumbnailCache = (isVideo) ? LocalDataSource.sThumbnailCacheVideo : LocalDataSource.sThumbnailCache;
+		return queryThumbnail(context, thumbId, origId, isVideo, thumbnailCache, timestamp);
+	}
 
-    private static final byte[] buildThumbnailForId(final Context context, final DiskCache thumbnailCache, final long thumbId,
-            final long origId, final boolean isVideo, final int thumbnailWidth, final int thumbnailHeight) {
-        if (origId == Shared.INVALID) {
-            return null;
-        }
-        try {
-            Bitmap bitmap = null;
-            Thread.sleep(1);
-            if (!isVideo) {
-                final String uriString = BASE_CONTENT_STRING_IMAGES + origId;
-                UriTexture.invalidateCache(thumbId, 1024);
-                try {
-                    bitmap = UriTexture.createFromUri(context, uriString, 1024, 1024, thumbId, null);
-                } catch (IOException e) {
-                    return null;
-                } catch (URISyntaxException e) {
-                    return null;
-                }
-            } else {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
-                new Thread() {
-                    public void run() {
-                        try {
-                            Thread.sleep(5000);
-                        } catch (InterruptedException e) {
-                            ;
-                        }
-                        try {
-                            MediaStore.Video.Thumbnails.cancelThumbnailRequest(context.getContentResolver(), origId);
-                        } catch (Exception e) {
-                            ;
-                        }
-                    }
-                }.start();
-                bitmap = MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(), origId,
-                        MediaStore.Video.Thumbnails.MICRO_KIND, null);
-            }
-            if (bitmap == null) {
-                return null;
-            }
-            final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight);
-            return retVal;
-        } catch (InterruptedException e) {
-            return null;
-        }
-    }
+	public static final ImageList getImageList(final Context context) {
+		if (sList != null)
+			return sList;
+		ImageList list = new ImageList();
+		final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
+		final ContentResolver cr = context.getContentResolver();
+		final Cursor cursorImages = cr.query(uriImages, THUMBNAIL_PROJECTION, null, null, null);
+		if (cursorImages != null && cursorImages.moveToFirst()) {
+			final int size = cursorImages.getCount();
+			final long[] ids = new long[size];
+			final long[] thumbnailIds = new long[size];
+			final long[] timestamp = new long[size];
+			final int[] orientation = new int[size];
+			int ctr = 0;
+			do {
+				if (Thread.interrupted()) {
+					break;
+				}
+				ids[ctr] = cursorImages.getLong(THUMBNAIL_ID_INDEX);
+				timestamp[ctr] = cursorImages.getLong(THUMBNAIL_DATE_MODIFIED_INDEX);
+				thumbnailIds[ctr] = Utils.Crc64Long(cursorImages.getString(THUMBNAIL_DATA_INDEX));
+				orientation[ctr] = cursorImages.getInt(THUMBNAIL_ORIENTATION_INDEX);
+				++ctr;
+			} while (cursorImages.moveToNext());
+			cursorImages.close();
+			list.ids = ids;
+			list.thumbids = thumbnailIds;
+			list.timestamp = timestamp;
+			list.orientation = orientation;
+		}
+		if (sList == null) {
+			sList = list;
+		}
+		return list;
+	}
 
-    public static final byte[] writeBitmapToCache(final DiskCache thumbnailCache, final long thumbId, final long origId,
-            final Bitmap bitmap, final int thumbnailWidth, final int thumbnailHeight) {
-        final int width = bitmap.getWidth();
-        final int height = bitmap.getHeight();
-        // Detect faces to find the focal point, otherwise fall back to the image center.
-        int focusX = width / 2;
-        int focusY = height / 2;
-        // We have commented out face detection since it slows down the generation of the thumbnail and screennail.
+	private static final byte[] queryThumbnail(final Context context, final long thumbId, final long origId, final boolean isVideo,
+	        final DiskCache thumbnailCache, final long timestamp) {
+		if (!((Gallery) context).isPaused()) {
+			final Thread thumbnailThread = THUMBNAIL_THREAD.getAndSet(null);
+			if (thumbnailThread != null) {
+				thumbnailThread.interrupt();
+			}
+		}
+		byte[] bitmap = thumbnailCache.get(thumbId, timestamp);
+		if (bitmap == null) {
+			Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+			final long time = SystemClock.uptimeMillis();
+			bitmap = buildThumbnailForId(context, thumbnailCache, thumbId, origId, isVideo, DEFAULT_THUMBNAIL_WIDTH,
+			        DEFAULT_THUMBNAIL_HEIGHT);
+			Log.i(TAG, "Built thumbnail and screennail for " + origId + " in " + (SystemClock.uptimeMillis() - time));
+			Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+		}
+		return bitmap;
+	}
 
-        // final FaceDetector faceDetector = new FaceDetector(width, height, 1);
-        // final FaceDetector.Face[] faces = new FaceDetector.Face[1];
-        // final int numFaces = faceDetector.findFaces(bitmap, faces);
-        // if (numFaces > 0 && faces[0].confidence() >= FaceDetector.Face.CONFIDENCE_THRESHOLD) {
-        // final PointF midPoint = new PointF();
-        // faces[0].getMidPoint(midPoint);
-        // focusX = (int) midPoint.x;
-        // focusY = (int) midPoint.y;
-        // }
+	private static final void buildThumbnails(final Context context) {
+		Log.i(TAG, "Preparing DiskCache for all thumbnails.");
+		ImageList list = getImageList(context);
+		final int size = (list.ids == null) ? 0 : list.ids.length;
+		final long[] ids = list.ids;
+		final long[] timestamp = list.timestamp;
+		final long[] thumbnailIds = list.thumbids;
+		final DiskCache thumbnailCache = LocalDataSource.sThumbnailCache;
+		for (int i = 0; i < size; ++i) {
+			if (Thread.interrupted()) {
+				return;
+			}
+			final long id = ids[i];
+			final long timeModifiedInSec = timestamp[i];
+			final long thumbnailId = thumbnailIds[i];
+			if (!thumbnailCache.isDataAvailable(thumbnailId, timeModifiedInSec * 1000)) {
+				buildThumbnailForId(context, thumbnailCache, thumbnailId, id, false, DEFAULT_THUMBNAIL_WIDTH,
+				        DEFAULT_THUMBNAIL_HEIGHT);
+			}
+		}
+		Log.i(TAG, "DiskCache ready for all thumbnails.");
+	}
 
-        // Crop to thumbnail aspect ratio biased towards the focus point.
-        int cropX;
-        int cropY;
-        int cropWidth;
-        int cropHeight;
-        float scaleFactor;
-        if (thumbnailWidth * height < thumbnailHeight * width) {
-            // Vertically constrained.
-            cropWidth = thumbnailWidth * height / thumbnailHeight;
-            cropX = Math.max(0, Math.min(focusX - cropWidth / 2, width - cropWidth));
-            cropY = 0;
-            cropHeight = height;
-            scaleFactor = (float) thumbnailHeight / height;
-        } else {
-            // Horizontally constrained.
-            cropHeight = thumbnailHeight * width / thumbnailWidth;
-            cropY = Math.max(0, Math.min(focusY - cropHeight / 2, height - cropHeight));
-            cropX = 0;
-            cropWidth = width;
-            scaleFactor = (float) thumbnailWidth / width;
-        }
-        final Bitmap finalBitmap = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.RGB_565);
-        final Canvas canvas = new Canvas(finalBitmap);
-        final Paint paint = new Paint();
-        paint.setFilterBitmap(true);
-        canvas.drawColor(0);
-        canvas.drawBitmap(bitmap, new Rect(cropX, cropY, cropX + cropWidth, cropY + cropHeight), new Rect(0, 0, thumbnailWidth,
-                thumbnailHeight), paint);
-        bitmap.recycle();
+	private static final byte[] buildThumbnailForId(final Context context, final DiskCache thumbnailCache, final long thumbId,
+	        final long origId, final boolean isVideo, final int thumbnailWidth, final int thumbnailHeight) {
+		if (origId == Shared.INVALID) {
+			return null;
+		}
+		try {
+			Bitmap bitmap = null;
+			Thread.sleep(1);
+			if (!isVideo) {
+				final String uriString = BASE_CONTENT_STRING_IMAGES + origId;
+				UriTexture.invalidateCache(thumbId, 1024);
+				try {
+					bitmap = UriTexture.createFromUri(context, uriString, 1024, 1024, thumbId, null);
+				} catch (IOException e) {
+					return null;
+				} catch (URISyntaxException e) {
+					return null;
+				}
+			} else {
+				Process.setThreadPriority(Process.THREAD_PRIORITY_DEFAULT);
+				new Thread() {
+					public void run() {
+						try {
+							Thread.sleep(5000);
+						} catch (InterruptedException e) {
+							;
+						}
+						try {
+							MediaStore.Video.Thumbnails.cancelThumbnailRequest(context.getContentResolver(), origId);
+						} catch (Exception e) {
+							;
+						}
+					}
+				}.start();
+				bitmap = MediaStore.Video.Thumbnails.getThumbnail(context.getContentResolver(), origId,
+				        MediaStore.Video.Thumbnails.MICRO_KIND, null);
+			}
+			if (bitmap == null) {
+				return null;
+			}
+			final byte[] retVal = writeBitmapToCache(thumbnailCache, thumbId, origId, bitmap, thumbnailWidth, thumbnailHeight);
+			return retVal;
+		} catch (InterruptedException e) {
+			return null;
+		}
+	}
 
-        // Store (long thumbnailId, short focusX, short focusY, JPEG data).
-        final ByteArrayOutputStream cacheOutput = new ByteArrayOutputStream(16384);
-        final DataOutputStream dataOutput = new DataOutputStream(cacheOutput);
-        byte[] retVal = null;
-        try {
-            dataOutput.writeLong(origId);
-            dataOutput.writeShort((int) ((focusX - cropX) * scaleFactor));
-            dataOutput.writeShort((int) ((focusY - cropY) * scaleFactor));
-            dataOutput.flush();
-            finalBitmap.compress(Bitmap.CompressFormat.JPEG, 80, cacheOutput);
-            retVal = cacheOutput.toByteArray();
-            synchronized (thumbnailCache) {
-                thumbnailCache.put(thumbId, retVal);
-            }
-            cacheOutput.close();
-        } catch (Exception e) {
-            ;
-        }
-        return retVal;
-    }
+	public static final byte[] writeBitmapToCache(final DiskCache thumbnailCache, final long thumbId, final long origId,
+	        final Bitmap bitmap, final int thumbnailWidth, final int thumbnailHeight) {
+		final int width = bitmap.getWidth();
+		final int height = bitmap.getHeight();
+		// Detect faces to find the focal point, otherwise fall back to the
+		// image center.
+		int focusX = width / 2;
+		int focusY = height / 2;
+		// We have commented out face detection since it slows down the
+		// generation of the thumbnail and screennail.
 
-    public CacheService() {
-        super("CacheService");
-    }
+		// final FaceDetector faceDetector = new FaceDetector(width, height, 1);
+		// final FaceDetector.Face[] faces = new FaceDetector.Face[1];
+		// final int numFaces = faceDetector.findFaces(bitmap, faces);
+		// if (numFaces > 0 && faces[0].confidence() >=
+		// FaceDetector.Face.CONFIDENCE_THRESHOLD) {
+		// final PointF midPoint = new PointF();
+		// faces[0].getMidPoint(midPoint);
+		// focusX = (int) midPoint.x;
+		// focusY = (int) midPoint.y;
+		// }
 
-    @Override
-    protected void onHandleIntent(final Intent intent) {
-        Log.i(TAG, "Starting CacheService");
-        if (Environment.getExternalStorageState() == Environment.MEDIA_BAD_REMOVAL) {
-            sAlbumCache.deleteAll();
-            putLocaleForAlbumCache(Locale.getDefault());
-        }
-        Locale locale = getLocaleForAlbumCache();
-        if (locale != null && locale.equals(Locale.getDefault())) {
-            // The cache is in the same locale as the system locale.
-            if (!isCacheReady(false)) {
-                // The albums and their items have not yet been cached, we need to run the service.
-                startNewCacheThread();
-            } else {
-                startNewCacheThreadForDirtySets();
-            }
-        } else {
-            // The locale has changed, we need to regenerate the strings.
-            sAlbumCache.deleteAll();
-            putLocaleForAlbumCache(Locale.getDefault());
-            startNewCacheThread();
-        }
-        if (intent.getBooleanExtra("checkthumbnails", false)) {
-            startNewThumbnailThread(this);
-        } else {
-            final Thread existingThread = THUMBNAIL_THREAD.getAndSet(null);
-            if (existingThread != null) {
-                existingThread.interrupt();
-            }
-        }
-    }
+		// Crop to thumbnail aspect ratio biased towards the focus point.
+		int cropX;
+		int cropY;
+		int cropWidth;
+		int cropHeight;
+		float scaleFactor;
+		if (thumbnailWidth * height < thumbnailHeight * width) {
+			// Vertically constrained.
+			cropWidth = thumbnailWidth * height / thumbnailHeight;
+			cropX = Math.max(0, Math.min(focusX - cropWidth / 2, width - cropWidth));
+			cropY = 0;
+			cropHeight = height;
+			scaleFactor = (float) thumbnailHeight / height;
+		} else {
+			// Horizontally constrained.
+			cropHeight = thumbnailHeight * width / thumbnailWidth;
+			cropY = Math.max(0, Math.min(focusY - cropHeight / 2, height - cropHeight));
+			cropX = 0;
+			cropWidth = width;
+			scaleFactor = (float) thumbnailWidth / width;
+		}
+		final Bitmap finalBitmap = Bitmap.createBitmap(thumbnailWidth, thumbnailHeight, Bitmap.Config.RGB_565);
+		final Canvas canvas = new Canvas(finalBitmap);
+		final Paint paint = new Paint();
+		paint.setFilterBitmap(true);
+		canvas.drawColor(0);
+		canvas.drawBitmap(bitmap, new Rect(cropX, cropY, cropX + cropWidth, cropY + cropHeight), new Rect(0, 0, thumbnailWidth,
+		        thumbnailHeight), paint);
+		bitmap.recycle();
 
-    private static final void putLocaleForAlbumCache(final Locale locale) {
-        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        final DataOutputStream dos = new DataOutputStream(bos);
-        try {
-            Utils.writeUTF(dos, locale.getCountry());
-            Utils.writeUTF(dos, locale.getLanguage());
-            Utils.writeUTF(dos, locale.getVariant());
-            dos.flush();
-            bos.flush();
-            final byte[] data = bos.toByteArray();
-            sAlbumCache.put(ALBUM_CACHE_LOCALE_INDEX, data);
-            sAlbumCache.flush();
-            dos.close();
-            bos.close();
-        } catch (IOException e) {
-            // Could not write locale to cache.
-            Log.i(TAG, "Error writing locale to cache.");
-            ;
-        }
-    }
+		// Store (long thumbnailId, short focusX, short focusY, JPEG data).
+		final ByteArrayOutputStream cacheOutput = new ByteArrayOutputStream(16384);
+		final DataOutputStream dataOutput = new DataOutputStream(cacheOutput);
+		byte[] retVal = null;
+		try {
+			dataOutput.writeLong(origId);
+			dataOutput.writeShort((int) ((focusX - cropX) * scaleFactor));
+			dataOutput.writeShort((int) ((focusY - cropY) * scaleFactor));
+			dataOutput.flush();
+			finalBitmap.compress(Bitmap.CompressFormat.JPEG, 80, cacheOutput);
+			retVal = cacheOutput.toByteArray();
+			synchronized (thumbnailCache) {
+				thumbnailCache.put(thumbId, retVal);
+			}
+			cacheOutput.close();
+		} catch (Exception e) {
+			;
+		}
+		return retVal;
+	}
 
-    private static final Locale getLocaleForAlbumCache() {
-        final byte[] data = sAlbumCache.get(ALBUM_CACHE_LOCALE_INDEX, 0);
-        if (data != null && data.length > 0) {
-            ByteArrayInputStream bis = new ByteArrayInputStream(data);
-            DataInputStream dis = new DataInputStream(bis);
-            try {
-                String country = Utils.readUTF(dis);
-                if (country == null)
-                    country = "";
-                String language = Utils.readUTF(dis);
-                if (language == null)
-                    language = "";
-                String variant = Utils.readUTF(dis);
-                if (variant == null)
-                    variant = "";
-                final Locale locale = new Locale(language, country, variant);
-                dis.close();
-                bis.close();
-                return locale;
-            } catch (IOException e) {
-                // Could not read locale in cache.
-                Log.i(TAG, "Error reading locale from cache.");
-                return null;
-            }
-        }
-        return null;
-    }
+	public CacheService() {
+		super("CacheService");
+	}
 
-    private static final void restartThread(final AtomicReference<Thread> threadRef, final String name, final Runnable action) {
-        // Create a new thread.
-        final Thread newThread = new Thread() {
-            public void run() {
-                try {
-                    action.run();
-                } finally {
-                    threadRef.compareAndSet(this, null);
-                }
-            }
-        };
-        newThread.setName(name);
-        newThread.start();
+	@Override
+	protected void onHandleIntent(final Intent intent) {
+		Log.i(TAG, "Starting CacheService");
+		if (Environment.getExternalStorageState() == Environment.MEDIA_BAD_REMOVAL) {
+			sAlbumCache.deleteAll();
+			putLocaleForAlbumCache(Locale.getDefault());
+		}
+		Locale locale = getLocaleForAlbumCache();
+		if (locale != null && locale.equals(Locale.getDefault())) {
+			// The cache is in the same locale as the system locale.
+			if (!isCacheReady(false)) {
+				// The albums and their items have not yet been cached, we need
+				// to run the service.
+				startNewCacheThread();
+			} else {
+				startNewCacheThreadForDirtySets();
+			}
+		} else {
+			// The locale has changed, we need to regenerate the strings.
+			sAlbumCache.deleteAll();
+			putLocaleForAlbumCache(Locale.getDefault());
+			startNewCacheThread();
+		}
+		if (intent.getBooleanExtra("checkthumbnails", false)) {
+			startNewThumbnailThread(this);
+		} else {
+			final Thread existingThread = THUMBNAIL_THREAD.getAndSet(null);
+			if (existingThread != null) {
+				existingThread.interrupt();
+			}
+		}
+	}
 
-        // Interrupt any existing thread.
-        final Thread existingThread = threadRef.getAndSet(newThread);
-        if (existingThread != null) {
-            existingThread.interrupt();
-        }
-    }
+	private static final void putLocaleForAlbumCache(final Locale locale) {
+		final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		final DataOutputStream dos = new DataOutputStream(bos);
+		try {
+			Utils.writeUTF(dos, locale.getCountry());
+			Utils.writeUTF(dos, locale.getLanguage());
+			Utils.writeUTF(dos, locale.getVariant());
+			dos.flush();
+			bos.flush();
+			final byte[] data = bos.toByteArray();
+			sAlbumCache.put(ALBUM_CACHE_LOCALE_INDEX, data);
+			sAlbumCache.flush();
+			dos.close();
+			bos.close();
+		} catch (IOException e) {
+			// Could not write locale to cache.
+			Log.i(TAG, "Error writing locale to cache.");
+			;
+		}
+	}
 
-    public static final void startNewThumbnailThread(final Context context) {
-        restartThread(THUMBNAIL_THREAD, "ThumbnailRefresh", new Runnable() {
-            public void run() {
-                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-                try {
-                    // It is an optimization to prevent the thumbnailer from running while the application loads
-                    Thread.sleep(THUMBNAILER_WAIT_IN_MS);
-                } catch (InterruptedException e) {
-                    return;
-                }
-                CacheService.buildThumbnails(context);
-            }
-        });
-    }
+	private static final Locale getLocaleForAlbumCache() {
+		final byte[] data = sAlbumCache.get(ALBUM_CACHE_LOCALE_INDEX, 0);
+		if (data != null && data.length > 0) {
+			ByteArrayInputStream bis = new ByteArrayInputStream(data);
+			DataInputStream dis = new DataInputStream(bis);
+			try {
+				String country = Utils.readUTF(dis);
+				if (country == null)
+					country = "";
+				String language = Utils.readUTF(dis);
+				if (language == null)
+					language = "";
+				String variant = Utils.readUTF(dis);
+				if (variant == null)
+					variant = "";
+				final Locale locale = new Locale(language, country, variant);
+				dis.close();
+				bis.close();
+				return locale;
+			} catch (IOException e) {
+				// Could not read locale in cache.
+				Log.i(TAG, "Error reading locale from cache.");
+				return null;
+			}
+		}
+		return null;
+	}
 
-    private void startNewCacheThread() {
-        restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
-            public void run() {
-                refresh(CacheService.this);
-            }
-        });
-    }
+	private static final void restartThread(final AtomicReference<Thread> threadRef, final String name, final Runnable action) {
+		// Create a new thread.
+		final Thread newThread = new Thread() {
+			public void run() {
+				try {
+					action.run();
+				} finally {
+					threadRef.compareAndSet(this, null);
+				}
+			}
+		};
+		newThread.setName(name);
+		newThread.start();
 
-    private void startNewCacheThreadForDirtySets() {
-        restartThread(CACHE_THREAD, "CacheRefreshDirtySets", new Runnable() {
-            public void run() {
-                refreshDirtySets(CacheService.this);
-            }
-        });
-    }
+		// Interrupt any existing thread.
+		final Thread existingThread = threadRef.getAndSet(newThread);
+		if (existingThread != null) {
+			existingThread.interrupt();
+		}
+	}
 
-    private static final byte[] concat(final byte[] A, final byte[] B) {
-        final byte[] C = (byte[]) new byte[A.length + B.length];
-        System.arraycopy(A, 0, C, 0, A.length);
-        System.arraycopy(B, 0, C, A.length, B.length);
-        return C;
-    }
+	public static final void startNewThumbnailThread(final Context context) {
+		restartThread(THUMBNAIL_THREAD, "ThumbnailRefresh", new Runnable() {
+			public void run() {
+				Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+				try {
+					// It is an optimization to prevent the thumbnailer from
+					// running while the application loads
+					Thread.sleep(THUMBNAILER_WAIT_IN_MS);
+				} catch (InterruptedException e) {
+					return;
+				}
+				CacheService.buildThumbnails(context);
+			}
+		});
+	}
 
-    private static final long[] toLongArray(final byte[] data) {
-        final ByteBuffer bBuffer = ByteBuffer.wrap(data);
-        final LongBuffer lBuffer = bBuffer.asLongBuffer();
-        final int numLongs = lBuffer.capacity();
-        final long[] retVal = new long[numLongs];
-        for (int i = 0; i < numLongs; ++i) {
-            retVal[i] = lBuffer.get(i);
-        }
-        return retVal;
-    }
+	private void startNewCacheThread() {
+		restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
+			public void run() {
+				refresh(CacheService.this);
+			}
+		});
+	}
 
-    private static final byte[] longToByteArray(final long l) {
-        final byte[] bArray = new byte[8];
-        final ByteBuffer bBuffer = ByteBuffer.wrap(bArray);
-        final LongBuffer lBuffer = bBuffer.asLongBuffer();
-        lBuffer.put(0, l);
-        return bArray;
-    }
+	private void startNewCacheThreadForDirtySets() {
+		restartThread(CACHE_THREAD, "CacheRefreshDirtySets", new Runnable() {
+			public void run() {
+				refreshDirtySets(CacheService.this);
+			}
+		});
+	}
 
-    private final static void refresh(final Context context) {
-        // First we build the album cache.
-        // This is the meta-data about the albums / buckets on the SD card.
-        Log.i(TAG, "Refreshing cache.");
-        int priority = Process.getThreadPriority(Process.myTid());
-        Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
-        sAlbumCache.deleteAll();
-        putLocaleForAlbumCache(Locale.getDefault());
+	private static final byte[] concat(final byte[] A, final byte[] B) {
+		final byte[] C = (byte[]) new byte[A.length + B.length];
+		System.arraycopy(A, 0, C, 0, A.length);
+		System.arraycopy(B, 0, C, A.length, B.length);
+		return C;
+	}
 
-        final ArrayList<MediaSet> sets = new ArrayList<MediaSet>();
-        LongSparseArray<MediaSet> acceleratedSets = new LongSparseArray<MediaSet>();
-        Log.i(TAG, "Building albums.");
-        final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
-        final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
-        final ContentResolver cr = context.getContentResolver();
+	private static final long toLong(final byte[] data) {
+		// 8 bytes for a long
+		if (data == null || data.length < 8)
+			return 0;
+		final ByteBuffer bBuffer = ByteBuffer.wrap(data);
+		final LongBuffer lBuffer = bBuffer.asLongBuffer();
+		final int numLongs = lBuffer.capacity();
+		return lBuffer.get(0);
+	}
 
-        final Cursor cursorImages = cr.query(uriImages, BUCKET_PROJECTION_IMAGES, null, null, DEFAULT_BUCKET_SORT_ORDER);
-        final Cursor cursorVideos = cr.query(uriVideos, BUCKET_PROJECTION_VIDEOS, null, null, DEFAULT_BUCKET_SORT_ORDER);
-        Cursor[] cursors = new Cursor[2];
-        cursors[0] = cursorImages;
-        cursors[1] = cursorVideos;
-        final SortCursor sortCursor = new SortCursor(cursors, Images.ImageColumns.BUCKET_DISPLAY_NAME, SortCursor.TYPE_STRING, true);
-        try {
-            if (sortCursor != null && sortCursor.moveToFirst()) {
-                sets.ensureCapacity(sortCursor.getCount());
-                acceleratedSets = new LongSparseArray<MediaSet>(sortCursor.getCount());
-                MediaSet cameraSet = new MediaSet();
-                cameraSet.mId = LocalDataSource.CAMERA_BUCKET_ID;
-                cameraSet.mName = context.getResources().getString(R.string.camera);
-                sets.add(cameraSet);
-                acceleratedSets.put(cameraSet.mId, cameraSet);
-                do {
-                    if (Thread.interrupted()) {
-                        return;
-                    }
-                    long setId = sortCursor.getLong(BUCKET_ID_INDEX);
-                    MediaSet mediaSet = findSet(setId, acceleratedSets);
-                    if (mediaSet == null) {
-                        mediaSet = new MediaSet();
-                        mediaSet.mId = setId;
-                        mediaSet.mName = sortCursor.getString(BUCKET_NAME_INDEX);
-                        sets.add(mediaSet);
-                        acceleratedSets.put(setId, mediaSet);
-                    }
-                    mediaSet.mHasImages |= (sortCursor.getCurrentCursorIndex() == 0);
-                    mediaSet.mHasVideos |= (sortCursor.getCurrentCursorIndex() == 1);
-                } while (sortCursor.moveToNext());
-                sortCursor.close();
-            }
-        } finally {
-            if (sortCursor != null)
-                sortCursor.close();
-        }
+	private static final long[] toLongArray(final byte[] data) {
+		final ByteBuffer bBuffer = ByteBuffer.wrap(data);
+		final LongBuffer lBuffer = bBuffer.asLongBuffer();
+		final int numLongs = lBuffer.capacity();
+		final long[] retVal = new long[numLongs];
+		for (int i = 0; i < numLongs; ++i) {
+			retVal[i] = lBuffer.get(i);
+		}
+		return retVal;
+	}
 
-        sAlbumCache.put(ALBUM_CACHE_INCOMPLETE_INDEX, sDummyData);
-        writeSetsToCache(sets);
-        Log.i(TAG, "Done building albums.");
-        // Now we must cache the items contained in every album / bucket.
-        populateMediaItemsForSets(context, sets, acceleratedSets, false);
-        sAlbumCache.delete(ALBUM_CACHE_INCOMPLETE_INDEX);
-        Process.setThreadPriority(priority);
-        if (QUEUE_DIRTY_ALL) {
-            QUEUE_DIRTY_ALL = false;
-            refresh(context);
-        }
-    }
+	private static final byte[] longToByteArray(final long l) {
+		final byte[] bArray = new byte[8];
+		final ByteBuffer bBuffer = ByteBuffer.wrap(bArray);
+		final LongBuffer lBuffer = bBuffer.asLongBuffer();
+		lBuffer.put(0, l);
+		return bArray;
+	}
 
-    private final static void refreshDirtySets(final Context context) {
-        final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
-        if (existingData != null && existingData.length > 0) {
-            final long[] ids = toLongArray(existingData);
-            final int numIds = ids.length;
-            if (numIds > 0) {
-                final ArrayList<MediaSet> sets = new ArrayList<MediaSet>(numIds);
-                final LongSparseArray<MediaSet> acceleratedSets = new LongSparseArray<MediaSet>(numIds);
-                for (int i = 0; i < numIds; ++i) {
-                    final MediaSet set = new MediaSet();
-                    set.mId = ids[i];
-                    sets.add(set);
-                    acceleratedSets.put(set.mId, set);
-                }
-                Log.i(TAG, "Refreshing dirty albums");
-                populateMediaItemsForSets(context, sets, acceleratedSets, true);
-            }
-        }
-        if (QUEUE_DIRTY_SET) {
-            QUEUE_DIRTY_SET = false;
-            refreshDirtySets(context);
-        } else {
-            sAlbumCache.delete(ALBUM_CACHE_DIRTY_BUCKET_INDEX);
-        }
-    }
+	private final static void refresh(final Context context) {
+		// First we build the album cache.
+		// This is the meta-data about the albums / buckets on the SD card.
+		Log.i(TAG, "Refreshing cache.");
+		int priority = Process.getThreadPriority(Process.myTid());
+		Process.setThreadPriority(Process.THREAD_PRIORITY_MORE_FAVORABLE);
+		sAlbumCache.deleteAll();
+		putLocaleForAlbumCache(Locale.getDefault());
 
-    private final static void populateMediaItemsForSets(final Context context, final ArrayList<MediaSet> sets,
-            final LongSparseArray<MediaSet> acceleratedSets, boolean useWhere) {
-        if (sets == null || sets.size() == 0 || Thread.interrupted()) {
-            return;
-        }
-        Log.i(TAG, "Building items.");
-        final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
-        final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
-        final ContentResolver cr = context.getContentResolver();
+		final ArrayList<MediaSet> sets = new ArrayList<MediaSet>();
+		LongSparseArray<MediaSet> acceleratedSets = new LongSparseArray<MediaSet>();
+		Log.i(TAG, "Building albums.");
+		final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
+		final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
+		final ContentResolver cr = context.getContentResolver();
 
-        String whereClause = null;
-        if (useWhere) {
-            int numSets = sets.size();
-            StringBuffer whereString = new StringBuffer(Images.ImageColumns.BUCKET_ID + " in (");
-            for (int i = 0; i < numSets; ++i) {
-                whereString.append(sets.get(i).mId);
-                if (i != numSets - 1) {
-                    whereString.append(",");
-                }
-            }
-            whereString.append(")");
-            whereClause = whereString.toString();
-            Log.i(TAG, "Updating dirty albums where " + whereClause);
-        }
+		final Cursor cursorImages = cr.query(uriImages, BUCKET_PROJECTION_IMAGES, null, null, DEFAULT_BUCKET_SORT_ORDER);
+		final Cursor cursorVideos = cr.query(uriVideos, BUCKET_PROJECTION_VIDEOS, null, null, DEFAULT_BUCKET_SORT_ORDER);
+		Cursor[] cursors = new Cursor[2];
+		cursors[0] = cursorImages;
+		cursors[1] = cursorVideos;
+		final SortCursor sortCursor = new SortCursor(cursors, Images.ImageColumns.BUCKET_DISPLAY_NAME, SortCursor.TYPE_STRING, true);
+		try {
+			if (sortCursor != null && sortCursor.moveToFirst()) {
+				sets.ensureCapacity(sortCursor.getCount());
+				acceleratedSets = new LongSparseArray<MediaSet>(sortCursor.getCount());
+				MediaSet cameraSet = new MediaSet();
+				cameraSet.mId = LocalDataSource.CAMERA_BUCKET_ID;
+				cameraSet.mName = context.getResources().getString(R.string.camera);
+				sets.add(cameraSet);
+				acceleratedSets.put(cameraSet.mId, cameraSet);
+				do {
+					if (Thread.interrupted()) {
+						return;
+					}
+					long setId = sortCursor.getLong(BUCKET_ID_INDEX);
+					MediaSet mediaSet = findSet(setId, acceleratedSets);
+					if (mediaSet == null) {
+						mediaSet = new MediaSet();
+						mediaSet.mId = setId;
+						mediaSet.mName = sortCursor.getString(BUCKET_NAME_INDEX);
+						sets.add(mediaSet);
+						acceleratedSets.put(setId, mediaSet);
+					}
+					mediaSet.mHasImages |= (sortCursor.getCurrentCursorIndex() == 0);
+					mediaSet.mHasVideos |= (sortCursor.getCurrentCursorIndex() == 1);
+				} while (sortCursor.moveToNext());
+				sortCursor.close();
+			}
+		} finally {
+			if (sortCursor != null)
+				sortCursor.close();
+		}
 
-        final Cursor cursorImages = cr.query(uriImages, PROJECTION_IMAGES, whereClause, null, DEFAULT_IMAGE_SORT_ORDER);
-        final Cursor cursorVideos = cr.query(uriVideos, PROJECTION_VIDEOS, whereClause, null, DEFAULT_VIDEO_SORT_ORDER);
-        final Cursor[] cursors = new Cursor[2];
-        cursors[0] = cursorImages;
-        cursors[1] = cursorVideos;
-        final SortCursor sortCursor = new SortCursor(cursors, Images.ImageColumns.DATE_TAKEN, SortCursor.TYPE_NUMERIC, true);
-        if (Thread.interrupted()) {
-            return;
-        }
-        try {
-            if (sortCursor != null && sortCursor.moveToFirst()) {
-                final int count = sortCursor.getCount();
-                final int numSets = sets.size();
-                final int approximateCountPerSet = count / numSets;
-                for (int i = 0; i < numSets; ++i) {
-                    final MediaSet set = sets.get(i);
-                    set.getItems().clear();
-                    set.setNumExpectedItems(approximateCountPerSet);
-                }
-                do {
-                    if (Thread.interrupted()) {
-                        return;
-                    }
-                    final MediaItem item = new MediaItem();
-                    final boolean isVideo = (sortCursor.getCurrentCursorIndex() == 1);
-                    if (isVideo) {
-                        populateVideoItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_VIDEOS);
-                    } else {
-                        populateMediaItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_IMAGES);
-                    }
-                    final long setId = sortCursor.getLong(MEDIA_BUCKET_ID_INDEX);
-                    final MediaSet set = findSet(setId, acceleratedSets);
-                    if (set != null) {
-                        set.getItems().add(item);
-                    }
-                } while (sortCursor.moveToNext());
-            }
-        } finally {
-            if (sortCursor != null) sortCursor.close();
-        }
-        if (sets.size() > 0) {
-            writeItemsToCache(sets);
-            Log.i(TAG, "Done building items.");
-        }
-    }
+		sAlbumCache.put(ALBUM_CACHE_INCOMPLETE_INDEX, sDummyData);
+		writeSetsToCache(sets);
+		Log.i(TAG, "Done building albums.");
+		// Now we must cache the items contained in every album / bucket.
+		populateMediaItemsForSets(context, sets, acceleratedSets, false);
+		sAlbumCache.delete(ALBUM_CACHE_INCOMPLETE_INDEX);
+		Process.setThreadPriority(priority);
 
-    private static final void writeSetsToCache(final ArrayList<MediaSet> sets) {
-        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        final int numSets = sets.size();
-        final DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos, 256));
-        try {
-            dos.writeInt(numSets);
-            for (int i = 0; i < numSets; ++i) {
-                if (Thread.interrupted()) {
-                    return;
-                }
-                final MediaSet set = sets.get(i);
-                dos.writeLong(set.mId);
-                Utils.writeUTF(dos, set.mName);
-                dos.writeBoolean(set.mHasImages);
-                dos.writeBoolean(set.mHasVideos);
-            }
-            dos.flush();
-            sAlbumCache.put(ALBUM_CACHE_METADATA_INDEX, bos.toByteArray());
-            dos.close();
-            if (numSets == 0) {
-                sAlbumCache.deleteAll();
-                putLocaleForAlbumCache(Locale.getDefault());
-            }
-            sAlbumCache.flush();
-        } catch (IOException e) {
-            Log.e(TAG, "Error writing albums to diskcache.");
-            sAlbumCache.deleteAll();
-            putLocaleForAlbumCache(Locale.getDefault());
-        }
-    }
+		// Complete any queued dirty requests
+		processQueuedDirty(context);
+	}
 
-    private static final void writeItemsToCache(final ArrayList<MediaSet> sets) {
-        final int numSets = sets.size();
-        for (int i = 0; i < numSets; ++i) {
-            if (Thread.interrupted()) {
-                return;
-            }
-            writeItemsForASet(sets.get(i));
-        }
-        sAlbumCache.flush();
-    }
+	private final static void refreshDirtySets(final Context context) {
+		final byte[] existingData = sAlbumCache.get(ALBUM_CACHE_DIRTY_BUCKET_INDEX, 0);
+		if (existingData != null && existingData.length > 0) {
+			final long[] ids = toLongArray(existingData);
+			final int numIds = ids.length;
+			if (numIds > 0) {
+				final ArrayList<MediaSet> sets = new ArrayList<MediaSet>(numIds);
+				final LongSparseArray<MediaSet> acceleratedSets = new LongSparseArray<MediaSet>(numIds);
+				for (int i = 0; i < numIds; ++i) {
+					final MediaSet set = new MediaSet();
+					set.mId = ids[i];
+					sets.add(set);
+					acceleratedSets.put(set.mId, set);
+				}
+				Log.i(TAG, "Refreshing dirty albums");
+				populateMediaItemsForSets(context, sets, acceleratedSets, true);
+			}
+		}
+		processQueuedDirty(context);
+		sAlbumCache.delete(ALBUM_CACHE_DIRTY_BUCKET_INDEX);
+	}
 
-    private static final void writeItemsForASet(final MediaSet set) {
-        final ByteArrayOutputStream bos = new ByteArrayOutputStream();
-        final DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos, 256));
-        try {
-            final ArrayList<MediaItem> items = set.getItems();
-            final int numItems = items.size();
-            dos.writeInt(numItems);
-            dos.writeLong(set.mMinTimestamp);
-            dos.writeLong(set.mMaxTimestamp);
-            for (int i = 0; i < numItems; ++i) {
-                MediaItem item = items.get(i);
-                if (set.mId == LocalDataSource.CAMERA_BUCKET_ID || set.mId == LocalDataSource.DOWNLOAD_BUCKET_ID) {
-                    // Reverse the display order for the camera bucket - want the latest first.
-                    item = items.get(numItems - i - 1);
-                }
-                dos.writeLong(item.mId);
-                Utils.writeUTF(dos, item.mCaption);
-                Utils.writeUTF(dos, item.mMimeType);
-                dos.writeInt(item.getMediaType());
-                dos.writeDouble(item.mLatitude);
-                dos.writeDouble(item.mLongitude);
-                dos.writeLong(item.mDateTakenInMs);
-                dos.writeBoolean(item.mTriedRetrievingExifDateTaken);
-                dos.writeLong(item.mDateAddedInSec);
-                dos.writeLong(item.mDateModifiedInSec);
-                dos.writeInt(item.mDurationInSec);
-                dos.writeInt((int) item.mRotation);
-                Utils.writeUTF(dos, item.mFilePath);
-            }
-            dos.flush();
-            sAlbumCache.put(set.mId, bos.toByteArray());
-            dos.close();
-        } catch (IOException e) {
-            Log.e(TAG, "Error writing to diskcache for set " + set.mName);
-            sAlbumCache.deleteAll();
-            putLocaleForAlbumCache(Locale.getDefault());
-        }
-    }
+	private static final long[] computeDirtySets(final Context context) {
+		final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
+		final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("distinct", "true").build();
+		final ContentResolver cr = context.getContentResolver();
 
-    private static final MediaSet findSet(final long id, final LongSparseArray<MediaSet> acceleratedTable) {
-        // This is the accelerated lookup table for the MediaSet based on set id.
-        return acceleratedTable.get(id);
-    }
+		final Cursor cursorImages = cr.query(uriImages, SENSE_PROJECTION, null, null, null);
+		final Cursor cursorVideos = cr.query(uriVideos, SENSE_PROJECTION, null, null, null);
+		Cursor[] cursors = new Cursor[2];
+		cursors[0] = cursorImages;
+		cursors[1] = cursorVideos;
+		final MergeCursor cursor = new MergeCursor(cursors);
+		long[] retVal = null;
+		try {
+			if (cursor.moveToFirst()) {
+				retVal = new long[cursor.getCount()];
+				int ctr = 0;
+				boolean allDirty = false;
+				do {
+					long setId = cursor.getLong(0);
+					retVal[ctr++] = setId;
+					byte[] data = sMetaAlbumCache.get(setId, 0);
+					if (data == null) {
+						// We need to refresh everything.
+						markDirty(context);
+						allDirty = true;
+					}
+					if (!allDirty) {
+						long maxAdded = cursor.getLong(1);
+						long oldMaxAdded = toLong(data);
+						if (maxAdded > oldMaxAdded) {
+							markDirty(context, setId);
+						}
+					}
+				} while (cursor.moveToNext());
+			}
+		} finally {
+			cursor.close();
+		}
+		processQueuedDirty(context);
+		return retVal;
+	}
+
+	private static final void processQueuedDirty(final Context context) {
+		if (QUEUE_DIRTY_SENSE) {
+			QUEUE_DIRTY_SENSE = false;
+			QUEUE_DIRTY_ALL = false;
+			QUEUE_DIRTY_SET = false;
+			computeDirtySets(context);
+		} else if (QUEUE_DIRTY_ALL) {
+			QUEUE_DIRTY_ALL = false;
+			QUEUE_DIRTY_SET = false;
+			QUEUE_DIRTY_SENSE = false;
+			refresh(context);
+		} else if (QUEUE_DIRTY_SET) {
+			QUEUE_DIRTY_SET = false;
+			// We don't mark QUEUE_DIRTY_SENSE because a set outside the dirty
+			// sets might have gotten modified.
+			refreshDirtySets(context);
+		}
+	}
+
+	private final static void populateMediaItemsForSets(final Context context, final ArrayList<MediaSet> sets,
+	        final LongSparseArray<MediaSet> acceleratedSets, boolean useWhere) {
+		if (sets == null || sets.size() == 0 || Thread.interrupted()) {
+			return;
+		}
+		Log.i(TAG, "Building items.");
+		final Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
+		final Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
+		final ContentResolver cr = context.getContentResolver();
+
+		String whereClause = null;
+		if (useWhere) {
+			int numSets = sets.size();
+			StringBuffer whereString = new StringBuffer(Images.ImageColumns.BUCKET_ID + " in (");
+			for (int i = 0; i < numSets; ++i) {
+				whereString.append(sets.get(i).mId);
+				if (i != numSets - 1) {
+					whereString.append(",");
+				}
+			}
+			whereString.append(")");
+			whereClause = whereString.toString();
+			Log.i(TAG, "Updating dirty albums where " + whereClause);
+		}
+
+		final Cursor cursorImages = cr.query(uriImages, PROJECTION_IMAGES, whereClause, null, DEFAULT_IMAGE_SORT_ORDER);
+		final Cursor cursorVideos = cr.query(uriVideos, PROJECTION_VIDEOS, whereClause, null, DEFAULT_VIDEO_SORT_ORDER);
+		final Cursor[] cursors = new Cursor[2];
+		cursors[0] = cursorImages;
+		cursors[1] = cursorVideos;
+		final SortCursor sortCursor = new SortCursor(cursors, Images.ImageColumns.DATE_TAKEN, SortCursor.TYPE_NUMERIC, true);
+		if (Thread.interrupted()) {
+			return;
+		}
+		try {
+			if (sortCursor != null && sortCursor.moveToFirst()) {
+				final int count = sortCursor.getCount();
+				final int numSets = sets.size();
+				final int approximateCountPerSet = count / numSets;
+				for (int i = 0; i < numSets; ++i) {
+					final MediaSet set = sets.get(i);
+					set.getItems().clear();
+					set.setNumExpectedItems(approximateCountPerSet);
+				}
+				do {
+					if (Thread.interrupted()) {
+						return;
+					}
+					final MediaItem item = new MediaItem();
+					final boolean isVideo = (sortCursor.getCurrentCursorIndex() == 1);
+					if (isVideo) {
+						populateVideoItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_VIDEOS);
+					} else {
+						populateMediaItemFromCursor(item, cr, sortCursor, CacheService.BASE_CONTENT_STRING_IMAGES);
+					}
+					final long setId = sortCursor.getLong(MEDIA_BUCKET_ID_INDEX);
+					final MediaSet set = findSet(setId, acceleratedSets);
+					if (set != null) {
+						set.getItems().add(item);
+					}
+				} while (sortCursor.moveToNext());
+			}
+		} finally {
+			if (sortCursor != null)
+				sortCursor.close();
+		}
+		if (sets.size() > 0) {
+			writeItemsToCache(sets);
+			Log.i(TAG, "Done building items.");
+		}
+	}
+
+	private static final void writeSetsToCache(final ArrayList<MediaSet> sets) {
+		final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		final int numSets = sets.size();
+		final DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos, 256));
+		try {
+			dos.writeInt(numSets);
+			for (int i = 0; i < numSets; ++i) {
+				if (Thread.interrupted()) {
+					return;
+				}
+				final MediaSet set = sets.get(i);
+				dos.writeLong(set.mId);
+				Utils.writeUTF(dos, set.mName);
+				dos.writeBoolean(set.mHasImages);
+				dos.writeBoolean(set.mHasVideos);
+			}
+			dos.flush();
+			sAlbumCache.put(ALBUM_CACHE_METADATA_INDEX, bos.toByteArray());
+			dos.close();
+			if (numSets == 0) {
+				sAlbumCache.deleteAll();
+				putLocaleForAlbumCache(Locale.getDefault());
+			}
+			sAlbumCache.flush();
+		} catch (IOException e) {
+			Log.e(TAG, "Error writing albums to diskcache.");
+			sAlbumCache.deleteAll();
+			putLocaleForAlbumCache(Locale.getDefault());
+		}
+	}
+
+	private static final void writeItemsToCache(final ArrayList<MediaSet> sets) {
+		final int numSets = sets.size();
+		for (int i = 0; i < numSets; ++i) {
+			if (Thread.interrupted()) {
+				return;
+			}
+			writeItemsForASet(sets.get(i));
+		}
+		writeMetaAlbumCache(sets);
+		sAlbumCache.flush();
+	}
+
+	private static final void writeMetaAlbumCache(ArrayList<MediaSet> sets) {
+		final int numSets = sets.size();
+		for (int i = 0; i < numSets; ++i) {
+			final MediaSet set = sets.get(i);
+			byte[] data = longToByteArray(set.mMaxAddedTimestamp);
+			sMetaAlbumCache.put(set.mId, data);
+		}
+		sMetaAlbumCache.flush();
+	}
+
+	private static final void writeItemsForASet(final MediaSet set) {
+		final ByteArrayOutputStream bos = new ByteArrayOutputStream();
+		final DataOutputStream dos = new DataOutputStream(new BufferedOutputStream(bos, 256));
+		try {
+			final ArrayList<MediaItem> items = set.getItems();
+			final int numItems = items.size();
+			dos.writeInt(numItems);
+			dos.writeLong(set.mMinTimestamp);
+			dos.writeLong(set.mMaxTimestamp);
+			for (int i = 0; i < numItems; ++i) {
+				MediaItem item = items.get(i);
+				if (set.mId == LocalDataSource.CAMERA_BUCKET_ID || set.mId == LocalDataSource.DOWNLOAD_BUCKET_ID) {
+					// Reverse the display order for the camera bucket - want
+					// the latest first.
+					item = items.get(numItems - i - 1);
+				}
+				dos.writeLong(item.mId);
+				Utils.writeUTF(dos, item.mCaption);
+				Utils.writeUTF(dos, item.mMimeType);
+				dos.writeInt(item.getMediaType());
+				dos.writeDouble(item.mLatitude);
+				dos.writeDouble(item.mLongitude);
+				dos.writeLong(item.mDateTakenInMs);
+				dos.writeBoolean(item.mTriedRetrievingExifDateTaken);
+				dos.writeLong(item.mDateAddedInSec);
+				dos.writeLong(item.mDateModifiedInSec);
+				dos.writeInt(item.mDurationInSec);
+				dos.writeInt((int) item.mRotation);
+				Utils.writeUTF(dos, item.mFilePath);
+			}
+			dos.flush();
+			sAlbumCache.put(set.mId, bos.toByteArray());
+			dos.close();
+		} catch (IOException e) {
+			Log.e(TAG, "Error writing to diskcache for set " + set.mName);
+			sAlbumCache.deleteAll();
+			putLocaleForAlbumCache(Locale.getDefault());
+		}
+	}
+
+	private static final MediaSet findSet(final long id, final LongSparseArray<MediaSet> acceleratedTable) {
+		// This is the accelerated lookup table for the MediaSet based on set
+		// id.
+		return acceleratedTable.get(id);
+	}
 }
diff --git a/src/com/cooliris/media/BackgroundLayer.java b/src/com/cooliris/media/BackgroundLayer.java
index 234e916..fef6bba 100644
--- a/src/com/cooliris/media/BackgroundLayer.java
+++ b/src/com/cooliris/media/BackgroundLayer.java
@@ -21,7 +21,7 @@
     private static final int ADAPTIVE_BACKGROUND_WIDTH = 256;
     private static final int ADAPTIVE_BACKGROUND_HEIGHT = 128;
 
-    BackgroundLayer(GridLayer layer) {
+    public BackgroundLayer(GridLayer layer) {
         mGridLayer = layer;
     }
 
diff --git a/src/com/cooliris/media/ConcatenatedDataSource.java b/src/com/cooliris/media/ConcatenatedDataSource.java
index f09b151..3a719b3 100644
--- a/src/com/cooliris/media/ConcatenatedDataSource.java
+++ b/src/com/cooliris/media/ConcatenatedDataSource.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 
+
 import android.util.Log;
 
 public final class ConcatenatedDataSource implements DataSource {
diff --git a/src/com/cooliris/media/DataSource.java b/src/com/cooliris/media/DataSource.java
index c05eacf..90b6df2 100644
--- a/src/com/cooliris/media/DataSource.java
+++ b/src/com/cooliris/media/DataSource.java
@@ -2,6 +2,7 @@
 
 import java.util.ArrayList;
 
+
 public interface DataSource {
     // Load the sets to be displayed.
     void loadMediaSets(final MediaFeed feed);
diff --git a/src/com/cooliris/media/FlatLocalDataSource.java b/src/com/cooliris/media/FlatLocalDataSource.java
deleted file mode 100644
index 87caca5..0000000
--- a/src/com/cooliris/media/FlatLocalDataSource.java
+++ /dev/null
@@ -1,35 +0,0 @@
-//package com.cooliris.media;
-//
-//// Deprecated class. Need to remove from perforce
-//
-//import java.util.ArrayList;
-//
-//public class FlatLocalDataSource implements MediaFeed.DataSource {
-//    private final boolean mIncludeImages;
-//    private final boolean mIncludeVideos;
-//    
-//    public FlatLocalDataSource(boolean includeImages, boolean includeVideos) {
-//        mIncludeImages = includeImages;
-//        mIncludeVideos = includeVideos;
-//    }
-//    
-//    public DiskCache getThumbnailCache() {
-//        return LocalDataSource.sThumbnailCache;
-//    }
-//
-//    public void loadItemsForSet(MediaFeed feed, MediaSet parentSet, int rangeStart, int rangeEnd) {
-//        // TODO Auto-generated method stub
-//        
-//    }
-//
-//    public void loadMediaSets(MediaFeed feed) {
-//        MediaSet set = feed.addMediaSet(0, this);
-//        set.name = "Local Media";
-//    }
-//
-//    public boolean performOperation(int operation, ArrayList<MediaBucket> mediaBuckets, Object data) {
-//        // TODO Auto-generated method stub
-//        return false;
-//    }
-//
-//}
diff --git a/src/com/cooliris/media/Gallery.java b/src/com/cooliris/media/Gallery.java
index 2a2a170..46fc3dd 100644
--- a/src/com/cooliris/media/Gallery.java
+++ b/src/com/cooliris/media/Gallery.java
@@ -2,6 +2,7 @@
 
 import java.io.IOException;
 import java.net.URISyntaxException;
+import java.util.HashMap;
 import java.util.TimeZone;
 
 import android.app.Activity;
@@ -27,349 +28,365 @@
 import com.cooliris.wallpaper.Slideshow;
 
 public final class Gallery extends Activity {
-    public static final TimeZone CURRENT_TIME_ZONE = TimeZone.getDefault();
-    public static float PIXEL_DENSITY = 0.0f;
-    public static boolean NEEDS_REFRESH = true;
+	public static final TimeZone CURRENT_TIME_ZONE = TimeZone.getDefault();
+	public static float PIXEL_DENSITY = 0.0f;
+	public static final int CROP_MSG_INTERNAL = 100;
 
-    private static final String TAG = "Gallery";
-    public static final int CROP_MSG_INTERNAL = 100;
-    private static final int CROP_MSG = 10;
-    private RenderView mRenderView = null;
-    private GridLayer mGridLayer;
-    private final Handler mHandler = new Handler();
-    private ReverseGeocoder mReverseGeocoder;
-    private boolean mPause;
-    private MediaScannerConnection mConnection;
-    private WakeLock mWakeLock;
-    private static final boolean TEST_WALLPAPER = false;
+	private static final String TAG = "Gallery";
+	private static final int CROP_MSG = 10;
+	private RenderView mRenderView = null;
+	private GridLayer mGridLayer;
+	private final Handler mHandler = new Handler();
+	private ReverseGeocoder mReverseGeocoder;
+	private boolean mPause;
+	private MediaScannerConnection mConnection;
+	private WakeLock mWakeLock;
+	private HashMap<String, Boolean> mAccountsEnabled;
+	private static final boolean TEST_WALLPAPER = false;
 
-    @Override
-    public void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
-        if (TEST_WALLPAPER || (isViewIntent() && getIntent().getData().equals(Images.Media.EXTERNAL_CONTENT_URI))) {
-            if (!imageManagerHasStorage) {
-                Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
-                finish();
-            } else {
-                PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
-                mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow.All");
-                mWakeLock.acquire();
-                Slideshow slideshow = new Slideshow(this);
-                slideshow.setDataSource(new RandomDataSource());
-                setContentView(slideshow);
-            }
-            return;
-        }
-        boolean isCacheReady = CacheService.isCacheReady(false);
-        CacheService.startCache(this, false);
-        if (PIXEL_DENSITY == 0.0f) {
-            DisplayMetrics metrics = new DisplayMetrics();
-            getWindowManager().getDefaultDisplay().getMetrics(metrics);
-            PIXEL_DENSITY = metrics.density;
-        }
-        mReverseGeocoder = new ReverseGeocoder(this);
-        mRenderView = new RenderView(this);
-        mGridLayer = new GridLayer(this, (int) (96.0f * PIXEL_DENSITY), (int) (72.0f * PIXEL_DENSITY), new GridLayoutInterface(4),
-                mRenderView);
-        mRenderView.setRootLayer(mGridLayer);
-        setContentView(mRenderView);
-        if (!isPickIntent() && !isViewIntent()) {
-            PicasaDataSource picasaDataSource = new PicasaDataSource(this);
-            if (imageManagerHasStorage) {
-                LocalDataSource localDataSource = new LocalDataSource(this);
-                ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
-                mGridLayer.setDataSource(combinedDataSource);
-            } else {
-                mGridLayer.setDataSource(picasaDataSource);
-            }
-            if (!imageManagerHasStorage) {
-                Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
-            } else {
-                if (!isCacheReady) {
-                    Toast.makeText(this, getResources().getString(R.string.loading_new), Toast.LENGTH_LONG).show();
-                } else {
-                    // Toast.makeText(this, getResources().getString(R.string.initializing), Toast.LENGTH_SHORT).show();
-                }
-            }
-        } else if (!isViewIntent()) {
-            Intent intent = getIntent();
-            if (intent != null) {
-                String type = intent.resolveType(this);
-                boolean includeImages = isImageType(type);
-                boolean includeVideos = isVideoType(type);
-                LocalDataSource localDataSource = new LocalDataSource(this);
-                ((LocalDataSource) localDataSource).setMimeFilter(!includeImages, !includeVideos);
-                if (includeImages) {
-                    PicasaDataSource picasaDataSource = new PicasaDataSource(this);
-                    if (imageManagerHasStorage) {
-                        ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
-                        mGridLayer.setDataSource(combinedDataSource);
-                    } else {
-                        mGridLayer.setDataSource(picasaDataSource);
-                    }
-                } else {
-                    mGridLayer.setDataSource(localDataSource);
-                }
-                mGridLayer.setPickIntent(true);
-                if (!imageManagerHasStorage) {
-                    Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
-                } else {
-                    Toast.makeText(this, getResources().getString(R.string.pick_prompt), Toast.LENGTH_LONG).show();
-                }
-            }
-        } else {
-            // View intent for images.
-            Uri uri = getIntent().getData();
-            boolean slideshow = getIntent().getBooleanExtra("slideshow", false);
-            SingleDataSource localDataSource = new SingleDataSource(this, uri.toString(), slideshow);
-            PicasaDataSource picasaDataSource = new PicasaDataSource(this);
-            ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
-            mGridLayer.setDataSource(combinedDataSource);
-            mGridLayer.setViewIntent(true, Utils.getBucketNameFromUri(uri));
-            if (SingleDataSource.isSingleImageMode(uri.toString())) {
-                mGridLayer.setSingleImage(false);
-            } else if (slideshow) {
-                mGridLayer.setSingleImage(true);
-                mGridLayer.startSlideshow();
-            }
-            // Toast.makeText(this, getResources().getString(R.string.initializing), Toast.LENGTH_SHORT).show();
-        }
-        Log.i(TAG, "onCreate");
-    }
+	@Override
+	public void onCreate(Bundle savedInstanceState) {
+		super.onCreate(savedInstanceState);
+		final boolean imageManagerHasStorage = ImageManager.quickHasStorage();
+		if (TEST_WALLPAPER || (isViewIntent() && getIntent().getData().equals(Images.Media.EXTERNAL_CONTENT_URI))) {
+			if (!imageManagerHasStorage) {
+				Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
+				finish();
+			} else {
+				PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+				mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow.All");
+				mWakeLock.acquire();
+				Slideshow slideshow = new Slideshow(this);
+				slideshow.setDataSource(new RandomDataSource());
+				setContentView(slideshow);
+			}
+			return;
+		}
+		final boolean isCacheReady = CacheService.isCacheReady(false);
+		CacheService.startCache(this, false);
+		if (PIXEL_DENSITY == 0.0f) {
+			DisplayMetrics metrics = new DisplayMetrics();
+			getWindowManager().getDefaultDisplay().getMetrics(metrics);
+			PIXEL_DENSITY = metrics.density;
+		}
+		mReverseGeocoder = new ReverseGeocoder(this);
+		mRenderView = new RenderView(this);
+		mGridLayer = new GridLayer(this, (int) (96.0f * PIXEL_DENSITY), (int) (72.0f * PIXEL_DENSITY), new GridLayoutInterface(4),
+		        mRenderView);
+		mRenderView.setRootLayer(mGridLayer);
+		setContentView(mRenderView);
+		
+		// Creating the DataSource objects
+		final PicasaDataSource picasaDataSource = new PicasaDataSource(this);
+		final LocalDataSource localDataSource = new LocalDataSource(this);
+		final ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
+		
+		// Depending upon the intent, we assign the right dataSource.
+		if (!isPickIntent() && !isViewIntent()) {
+			if (imageManagerHasStorage) {
+				mGridLayer.setDataSource(combinedDataSource);
+			} else {
+				mGridLayer.setDataSource(picasaDataSource);
+			}
+			if (!imageManagerHasStorage) {
+				Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
+			} else if (!isCacheReady) {
+				Toast.makeText(this, getResources().getString(R.string.loading_new), Toast.LENGTH_LONG).show();
+			}
+		} else if (!isViewIntent()) {
+			final Intent intent = getIntent();
+			if (intent != null) {
+				final String type = intent.resolveType(this);
+				boolean includeImages = isImageType(type);
+				boolean includeVideos = isVideoType(type);
+				((LocalDataSource) localDataSource).setMimeFilter(!includeImages, !includeVideos);
+				if (includeImages) {
+					if (imageManagerHasStorage) {
+						mGridLayer.setDataSource(combinedDataSource);
+					} else {
+						mGridLayer.setDataSource(picasaDataSource);
+					}
+				} else {
+					mGridLayer.setDataSource(localDataSource);
+				}
+				mGridLayer.setPickIntent(true);
+				if (!imageManagerHasStorage) {
+					Toast.makeText(this, getResources().getString(R.string.no_sd_card), Toast.LENGTH_LONG).show();
+				} else {
+					Toast.makeText(this, getResources().getString(R.string.pick_prompt), Toast.LENGTH_LONG).show();
+				}
+			}
+		} else {
+			// View intent for images.
+			Uri uri = getIntent().getData();
+			boolean slideshow = getIntent().getBooleanExtra("slideshow", false);
+			final SingleDataSource singleDataSource = new SingleDataSource(this, uri.toString(), slideshow);
+			final ConcatenatedDataSource singleCombinedDataSource = new ConcatenatedDataSource(singleDataSource, picasaDataSource);
+			mGridLayer.setDataSource(singleCombinedDataSource);
+			mGridLayer.setViewIntent(true, Utils.getBucketNameFromUri(uri));
+			if (SingleDataSource.isSingleImageMode(uri.toString())) {
+				mGridLayer.setSingleImage(false);
+			} else if (slideshow) {
+				mGridLayer.setSingleImage(true);
+				mGridLayer.startSlideshow();
+			}
+		}
+		// We record the set of enabled accounts for picasa.
+		mAccountsEnabled = PicasaDataSource.getAccountStatus(this);
+		Log.i(TAG, "onCreate");
+	}
 
-    public ReverseGeocoder getReverseGeocoder() {
-        return mReverseGeocoder;
-    }
+	public ReverseGeocoder getReverseGeocoder() {
+		return mReverseGeocoder;
+	}
 
-    public Handler getHandler() {
-        return mHandler;
-    }
+	public Handler getHandler() {
+		return mHandler;
+	}
 
-    @Override
-    public void onRestart() {
-        super.onRestart();
-    }
+	@Override
+	public void onRestart() {
+		super.onRestart();
+	}
 
-    @Override
-    public void onStart() {
-        super.onStart();
-    }
+	@Override
+	public void onStart() {
+		super.onStart();
+	}
 
-    @Override
-    public void onResume() {
-        super.onResume();
-        if (mRenderView != null)
-            mRenderView.onResume();
-        if (NEEDS_REFRESH) {
-            NEEDS_REFRESH = false;
-            CacheService.markDirtyImmediate(LocalDataSource.CAMERA_BUCKET_ID);
-            CacheService.markDirtyImmediate(LocalDataSource.DOWNLOAD_BUCKET_ID);
-            CacheService.startCache(this, false);
-        }
-        mPause = false;
-    }
+	@Override
+	public void onResume() {
+		super.onResume();
+		if (mRenderView != null)
+			mRenderView.onResume();
+		if (mPause) {
+			// We check to see if the authenticated accounts have changed, and
+			// if so, reload the datasource.
+			HashMap<String, Boolean> accountsEnabled = PicasaDataSource.getAccountStatus(this);
+			String[] keys = new String[accountsEnabled.size()];
+			keys = accountsEnabled.keySet().toArray(keys);
+			int numKeys = keys.length;
+			for (int i = 0; i < numKeys; ++i) {
+				String key = keys[i];
+				boolean newValue = accountsEnabled.get(key).booleanValue();
+				boolean oldValue = false;
+				Boolean oldValObj = mAccountsEnabled.get(key);
+				if (oldValObj != null) {
+					oldValue = oldValObj.booleanValue();
+				}
+				if (oldValue != newValue) {
+					// Reload the datasource.
+					mGridLayer.setDataSource(mGridLayer.getDataSource());
+					break;
+				}
+			}
+			mAccountsEnabled = accountsEnabled;
+			mPause = false;
+		}
+	}
 
-    @Override
-    public void onPause() {
-        super.onPause();
-        if (mRenderView != null)
-            mRenderView.onPause();
-        mPause = true;
-    }
+	@Override
+	public void onPause() {
+		super.onPause();
+		if (mRenderView != null)
+			mRenderView.onPause();
+		mPause = true;
+	}
 
-    public boolean isPaused() {
-        return mPause;
-    }
+	public boolean isPaused() {
+		return mPause;
+	}
 
-    @Override
-    public void onStop() {
-        super.onStop();
-        if (mGridLayer != null)
-            mGridLayer.stop();
-        if (mReverseGeocoder != null) {
-            mReverseGeocoder.flushCache();
-        }
-        LocalDataSource.sThumbnailCache.flush();
-        LocalDataSource.sThumbnailCacheVideo.flush();
-        PicasaDataSource.sThumbnailCache.flush();
-        CacheService.startCache(this, true);
-    }
+	@Override
+	public void onStop() {
+		super.onStop();
+		if (mGridLayer != null)
+			mGridLayer.stop();
+		if (mReverseGeocoder != null) {
+			mReverseGeocoder.flushCache();
+		}
+		LocalDataSource.sThumbnailCache.flush();
+		LocalDataSource.sThumbnailCacheVideo.flush();
+		PicasaDataSource.sThumbnailCache.flush();
+		CacheService.startCache(this, true);
+	}
 
-    @Override
-    public void onDestroy() {
-        // Force GLThread to exit.
-        setContentView(R.layout.main);
-        if (mGridLayer != null) {
-            DataSource dataSource = mGridLayer.getDataSource();
-            if (dataSource != null) {
-                dataSource.shutdown();
-            }
-            mGridLayer.shutdown();
-        }
-        if (mWakeLock != null) {
-            if (mWakeLock.isHeld()) {
-                mWakeLock.release();
-            }
-            mWakeLock = null;
-        }
-        if (mReverseGeocoder != null)
-            mReverseGeocoder.shutdown();
-        if (mRenderView != null) {
-            mRenderView.shutdown();
-            mRenderView = null;
-        }
-        mGridLayer = null;
-        super.onDestroy();
-        Log.i(TAG, "onDestroy");
-    }
+	@Override
+	public void onDestroy() {
+		// Force GLThread to exit.
+		setContentView(R.layout.main);
+		if (mGridLayer != null) {
+			DataSource dataSource = mGridLayer.getDataSource();
+			if (dataSource != null) {
+				dataSource.shutdown();
+			}
+			mGridLayer.shutdown();
+		}
+		if (mWakeLock != null) {
+			if (mWakeLock.isHeld()) {
+				mWakeLock.release();
+			}
+			mWakeLock = null;
+		}
+		if (mReverseGeocoder != null)
+			mReverseGeocoder.shutdown();
+		if (mRenderView != null) {
+			mRenderView.shutdown();
+			mRenderView = null;
+		}
+		mGridLayer = null;
+		super.onDestroy();
+		Log.i(TAG, "onDestroy");
+	}
 
-    @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        if (mGridLayer != null) {
-            mGridLayer.markDirty(30);
-        }
-        if (mRenderView != null)
-            mRenderView.requestRender();
-        Log.i(TAG, "onConfigurationChanged");
-    }
+	@Override
+	public void onConfigurationChanged(Configuration newConfig) {
+		super.onConfigurationChanged(newConfig);
+		if (mGridLayer != null) {
+			mGridLayer.markDirty(30);
+		}
+		if (mRenderView != null)
+			mRenderView.requestRender();
+		Log.i(TAG, "onConfigurationChanged");
+	}
 
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (mRenderView != null) {
-            return mRenderView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
-        } else {
-            return super.onKeyDown(keyCode, event);
-        }
-    }
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event) {
+		if (mRenderView != null) {
+			return mRenderView.onKeyDown(keyCode, event) || super.onKeyDown(keyCode, event);
+		} else {
+			return super.onKeyDown(keyCode, event);
+		}
+	}
 
-    private boolean isPickIntent() {
-        String action = getIntent().getAction();
-        return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
-    }
+	private boolean isPickIntent() {
+		String action = getIntent().getAction();
+		return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
+	}
 
-    private boolean isViewIntent() {
-        String action = getIntent().getAction();
-        return Intent.ACTION_VIEW.equals(action);
-    }
+	private boolean isViewIntent() {
+		String action = getIntent().getAction();
+		return Intent.ACTION_VIEW.equals(action);
+	}
 
-    private boolean isImageType(String type) {
-        return type.equals("vnd.android.cursor.dir/image") || type.equals("image/*");
-    }
+	private boolean isImageType(String type) {
+		return type.equals("vnd.android.cursor.dir/image") || type.equals("image/*");
+	}
 
-    private boolean isVideoType(String type) {
-        return type.equals("vnd.android.cursor.dir/video") || type.equals("video/*");
-    }
+	private boolean isVideoType(String type) {
+		return type.equals("vnd.android.cursor.dir/video") || type.equals("video/*");
+	}
 
-    @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        switch (requestCode) {
-        case CROP_MSG: {
-            if (resultCode == RESULT_OK) {
-                setResult(resultCode, data);
-                finish();
-            }
-            break;
-        }
-        case CROP_MSG_INTERNAL: {
-            // We cropped an image, we must try to set the focus of the camera to that image.
-            if (resultCode == RESULT_OK) {
-                String contentUri = data.getAction();
-                if (mGridLayer != null) {
-                    mGridLayer.focusItem(contentUri);
-                }
-            }
-            break;
-        }
-        }
-    }
+	@Override
+	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+		switch (requestCode) {
+		case CROP_MSG: {
+			if (resultCode == RESULT_OK) {
+				setResult(resultCode, data);
+				finish();
+			}
+			break;
+		}
+		case CROP_MSG_INTERNAL: {
+			// We cropped an image, we must try to set the focus of the camera
+			// to that image.
+			if (resultCode == RESULT_OK) {
+				String contentUri = data.getAction();
+				if (mGridLayer != null) {
+					mGridLayer.focusItem(contentUri);
+				}
+			}
+			break;
+		}
+		}
+	}
 
-    @Override
-    public void onLowMemory() {
-        if (mRenderView != null) {
-            mRenderView.handleLowMemory();
-        }
-    }
+	@Override
+	public void onLowMemory() {
+		if (mRenderView != null) {
+			mRenderView.handleLowMemory();
+		}
+	}
 
-    public void launchCropperOrFinish(final MediaItem item) {
-        final Bundle myExtras = getIntent().getExtras();
-        String cropValue = myExtras != null ? myExtras.getString("crop") : null;
-        final String contentUri = item.mContentUri;
-        if (cropValue != null) {
-            Bundle newExtras = new Bundle();
-            if (cropValue.equals("circle")) {
-                newExtras.putString("circleCrop", "true");
-            }
-            Intent cropIntent = new Intent();
-            cropIntent.setData(Uri.parse(contentUri));
-            cropIntent.setClass(this, CropImage.class);
-            cropIntent.putExtras(newExtras);
-            // Pass through any extras that were passed in.
-            cropIntent.putExtras(myExtras);
-            startActivityForResult(cropIntent, CROP_MSG);
-        } else {
-            if (contentUri.startsWith("http://")) {
-                // This is a http uri, we must save it locally first and generate a content uri from it.
-                final ProgressDialog dialog = ProgressDialog.show(this, this.getResources().getString(R.string.initializing),
-                        getResources().getString(R.string.running_face_detection), true, false);
-                if (contentUri != null) {
-                    MediaScannerConnection.MediaScannerConnectionClient client = new MediaScannerConnection.MediaScannerConnectionClient() {
-                        public void onMediaScannerConnected() {
-                            if (mConnection != null) {
-                                try {
-                                    final String path = UriTexture.writeHttpDataInDirectory(Gallery.this, contentUri,
-                                            LocalDataSource.DOWNLOAD_BUCKET_NAME);
-                                    if (path != null) {
-                                        mConnection.scanFile(path, item.mMimeType);
-                                    } else {
-                                        shutdown("");
-                                    }
-                                } catch (Exception e) {
-                                    shutdown("");
-                                }
-                            }
-                        }
+	public void launchCropperOrFinish(final MediaItem item) {
+		final Bundle myExtras = getIntent().getExtras();
+		String cropValue = myExtras != null ? myExtras.getString("crop") : null;
+		final String contentUri = item.mContentUri;
+		if (cropValue != null) {
+			Bundle newExtras = new Bundle();
+			if (cropValue.equals("circle")) {
+				newExtras.putString("circleCrop", "true");
+			}
+			Intent cropIntent = new Intent();
+			cropIntent.setData(Uri.parse(contentUri));
+			cropIntent.setClass(this, CropImage.class);
+			cropIntent.putExtras(newExtras);
+			// Pass through any extras that were passed in.
+			cropIntent.putExtras(myExtras);
+			startActivityForResult(cropIntent, CROP_MSG);
+		} else {
+			if (contentUri.startsWith("http://")) {
+				// This is a http uri, we must save it locally first and
+				// generate a content uri from it.
+				final ProgressDialog dialog = ProgressDialog.show(this, this.getResources().getString(R.string.initializing),
+				        getResources().getString(R.string.running_face_detection), true, false);
+				if (contentUri != null) {
+					MediaScannerConnection.MediaScannerConnectionClient client = new MediaScannerConnection.MediaScannerConnectionClient() {
+						public void onMediaScannerConnected() {
+							if (mConnection != null) {
+								try {
+									final String path = UriTexture.writeHttpDataInDirectory(Gallery.this, contentUri,
+									        LocalDataSource.DOWNLOAD_BUCKET_NAME);
+									if (path != null) {
+										mConnection.scanFile(path, item.mMimeType);
+									} else {
+										shutdown("");
+									}
+								} catch (Exception e) {
+									shutdown("");
+								}
+							}
+						}
 
-                        public void onScanCompleted(String path, Uri uri) {
-                            shutdown(uri.toString());
-                        }
+						public void onScanCompleted(String path, Uri uri) {
+							shutdown(uri.toString());
+						}
 
-                        public void shutdown(String uri) {
-                            dialog.dismiss();
-                            performReturn(myExtras, uri.toString());
-                            if (mConnection != null) {
-                                mConnection.disconnect();
-                            }
-                        }
-                    };
-                    MediaScannerConnection connection = new MediaScannerConnection(Gallery.this, client);
-                    connection.connect();
-                    mConnection = connection;
-                }
-            } else {
-                performReturn(myExtras, contentUri);
-            }
-        }
-    }
+						public void shutdown(String uri) {
+							dialog.dismiss();
+							performReturn(myExtras, uri.toString());
+							if (mConnection != null) {
+								mConnection.disconnect();
+							}
+						}
+					};
+					MediaScannerConnection connection = new MediaScannerConnection(Gallery.this, client);
+					connection.connect();
+					mConnection = connection;
+				}
+			} else {
+				performReturn(myExtras, contentUri);
+			}
+		}
+	}
 
-    private void performReturn(Bundle myExtras, String contentUri) {
-        Intent result = new Intent(null, Uri.parse(contentUri));
-        if (myExtras != null && myExtras.getBoolean("return-data")) {
-            // The size of a transaction should be below 100K.
-            Bitmap bitmap = null;
-            try {
-                bitmap = UriTexture.createFromUri(this, contentUri, 1024, 1024, 0, null);
-            } catch (IOException e) {
-                ;
-            } catch (URISyntaxException e) {
-                ;
-            }
-            if (bitmap != null) {
-                result.putExtra("data", bitmap);
-            }
-        }
-        setResult(RESULT_OK, result);
-        finish();
-    }
+	private void performReturn(Bundle myExtras, String contentUri) {
+		Intent result = new Intent(null, Uri.parse(contentUri));
+		if (myExtras != null && myExtras.getBoolean("return-data")) {
+			// The size of a transaction should be below 100K.
+			Bitmap bitmap = null;
+			try {
+				bitmap = UriTexture.createFromUri(this, contentUri, 1024, 1024, 0, null);
+			} catch (IOException e) {
+				;
+			} catch (URISyntaxException e) {
+				;
+			}
+			if (bitmap != null) {
+				result.putExtra("data", bitmap);
+			}
+		}
+		setResult(RESULT_OK, result);
+		finish();
+	}
 }
diff --git a/src/com/cooliris/media/GridCameraManager.java b/src/com/cooliris/media/GridCameraManager.java
index 0e43ef3..b4eb1c2 100644
--- a/src/com/cooliris/media/GridCameraManager.java
+++ b/src/com/cooliris/media/GridCameraManager.java
@@ -1,5 +1,6 @@
 package com.cooliris.media;
 
+
 public final class GridCameraManager {
     private final GridCamera mCamera;
     private static final Pool<Vector3f> sPool;
diff --git a/src/com/cooliris/media/GridInputProcessor.java b/src/com/cooliris/media/GridInputProcessor.java
index c7050cb..94a15d8 100644
--- a/src/com/cooliris/media/GridInputProcessor.java
+++ b/src/com/cooliris/media/GridInputProcessor.java
@@ -182,6 +182,9 @@
                     layer.setZoomValue(1.0f);
             }
             if (keyCode == KeyEvent.KEYCODE_MENU) {
+            	if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
+            		return true;
+            	}
                 if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
                     layer.enterSelectionMode();
                 else
diff --git a/src/com/cooliris/media/GridLayer.java b/src/com/cooliris/media/GridLayer.java
index dc2b09f..8cd05c2 100644
--- a/src/com/cooliris/media/GridLayer.java
+++ b/src/com/cooliris/media/GridLayer.java
@@ -7,1426 +7,1437 @@
 import android.opengl.GLU;
 import android.os.PowerManager;
 import android.os.PowerManager.WakeLock;
+import android.util.Log;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.content.Context;
 
 public final class GridLayer extends RootLayer implements MediaFeed.Listener, TimeBar.Listener {
-    public static final int STATE_MEDIA_SETS = 0;
-    public static final int STATE_GRID_VIEW = 1;
-    public static final int STATE_FULL_SCREEN = 2;
-    public static final int STATE_TIMELINE = 3;
+	public static final int STATE_MEDIA_SETS = 0;
+	public static final int STATE_GRID_VIEW = 1;
+	public static final int STATE_FULL_SCREEN = 2;
+	public static final int STATE_TIMELINE = 3;
 
-    public static final int ANCHOR_LEFT = 0;
-    public static final int ANCHOR_RIGHT = 1;
-    public static final int ANCHOR_CENTER = 2;
+	public static final int ANCHOR_LEFT = 0;
+	public static final int ANCHOR_RIGHT = 1;
+	public static final int ANCHOR_CENTER = 2;
 
-    public static final int MAX_ITEMS_PER_SLOT = 12;
-    public static final int MAX_DISPLAYED_ITEMS_PER_SLOT = 4;
-    public static final int MAX_DISPLAY_SLOTS = 96;
-    public static final int MAX_ITEMS_DRAWABLE = MAX_ITEMS_PER_SLOT * MAX_DISPLAY_SLOTS;
+	public static final int MAX_ITEMS_PER_SLOT = 12;
+	public static final int MAX_DISPLAYED_ITEMS_PER_SLOT = 4;
+	public static final int MAX_DISPLAY_SLOTS = 96;
+	public static final int MAX_ITEMS_DRAWABLE = MAX_ITEMS_PER_SLOT * MAX_DISPLAY_SLOTS;
 
-    private static final float SLIDESHOW_TRANSITION_TIME = 3.5f;
+	private static final float SLIDESHOW_TRANSITION_TIME = 3.5f;
 
-    private static HudLayer sHud;
-    private int mState;
-    private static final IndexRange sBufferedVisibleRange = new IndexRange();
-    private static final IndexRange sVisibleRange = new IndexRange();
-    private static final IndexRange sPreviousDataRange = new IndexRange();
-    private static final IndexRange sCompleteRange = new IndexRange();
-    
-    private static final Pool<Vector3f> sTempVec;
-    private static final Pool<Vector3f> sTempVecAlt;
-    static {
-        Vector3f[] vectorPool = new Vector3f[128];
-        int length = vectorPool.length;
-        for (int i = 0; i < length; ++i) {
-            vectorPool[i] = new Vector3f();
-        }
-        Vector3f[] vectorPoolRenderThread = new Vector3f[128];
-        length = vectorPoolRenderThread.length;
-        for (int i = 0; i < length; ++i) {
-            vectorPoolRenderThread[i] = new Vector3f();
-        }
-        sTempVec = new Pool<Vector3f>(vectorPool);
-        sTempVecAlt = new Pool<Vector3f>(vectorPoolRenderThread);
-    }
-    
-    private static final ArrayList<MediaItem> sTempList = new ArrayList<MediaItem>();
-    private static final MediaItem[] sTempHash = new MediaItem[64];
-    
-    private static final Vector3f sDeltaAnchorPositionUncommited = new Vector3f();
-    private static Vector3f sDeltaAnchorPosition = new Vector3f();
+	private static HudLayer sHud;
+	private int mState;
+	private static final IndexRange sBufferedVisibleRange = new IndexRange();
+	private static final IndexRange sVisibleRange = new IndexRange();
+	private static final IndexRange sPreviousDataRange = new IndexRange();
+	private static final IndexRange sCompleteRange = new IndexRange();
 
-    // The display primitives.
-    private GridDrawables mDrawables;
-    private float mSelectedAlpha = 0.0f;
-    private float mTargetAlpha = 0.0f;
+	private static final Pool<Vector3f> sTempVec;
+	private static final Pool<Vector3f> sTempVecAlt;
+	static {
+		Vector3f[] vectorPool = new Vector3f[128];
+		int length = vectorPool.length;
+		for (int i = 0; i < length; ++i) {
+			vectorPool[i] = new Vector3f();
+		}
+		Vector3f[] vectorPoolRenderThread = new Vector3f[128];
+		length = vectorPoolRenderThread.length;
+		for (int i = 0; i < length; ++i) {
+			vectorPoolRenderThread[i] = new Vector3f();
+		}
+		sTempVec = new Pool<Vector3f>(vectorPool);
+		sTempVecAlt = new Pool<Vector3f>(vectorPoolRenderThread);
+	}
 
-    private GridCamera mCamera;
-    private GridCameraManager mCameraManager;
-    private GridDrawManager mDrawManager;
-    private GridInputProcessor mInputProcessor;
+	private static final ArrayList<MediaItem> sTempList = new ArrayList<MediaItem>();
+	private static final MediaItem[] sTempHash = new MediaItem[64];
 
-    private boolean mFeedAboutToChange;
-    private boolean mPerformingLayoutChange;
-    private boolean mFeedChanged;
+	private static final Vector3f sDeltaAnchorPositionUncommited = new Vector3f();
+	private static Vector3f sDeltaAnchorPosition = new Vector3f();
 
-    private final LayoutInterface mLayoutInterface;
-    private static final LayoutInterface sfullScreenLayoutInterface = new GridLayoutInterface(1);
-    
-    private MediaFeed mMediaFeed;
-    private boolean mInAlbum = false;
-    private int mCurrentExpandedSlot;
+	// The display primitives.
+	private GridDrawables mDrawables;
+	private float mSelectedAlpha = 0.0f;
+	private float mTargetAlpha = 0.0f;
 
-    private static final DisplayList sDisplayList = new DisplayList();
-    private static final DisplayItem[] sDisplayItems = new DisplayItem[MAX_ITEMS_DRAWABLE];
-    private static final DisplaySlot[] sDisplaySlots = new DisplaySlot[MAX_DISPLAY_SLOTS];
-    private static ArrayList<MediaItem> sVisibleItems;
-    
-    private float mTimeElapsedSinceTransition;
-    private BackgroundLayer mBackground;
-    private boolean mLocationFilter;
-    private float mZoomValue = 1.0f;
-    private float mCurrentFocusItemWidth = 1.0f;
-    private float mCurrentFocusItemHeight = 1.0f;
-    private float mTimeElapsedSinceGridViewReady = 0.0f;
+	private GridCamera mCamera;
+	private GridCameraManager mCameraManager;
+	private GridDrawManager mDrawManager;
+	private GridInputProcessor mInputProcessor;
 
-    private boolean mSlideshowMode;
-    private boolean mNoDeleteMode = false;
-    private float mTimeElapsedSinceView;
-    private static final MediaBucketList sBucketList = new MediaBucketList();
-    private float mTimeElapsedSinceStackViewReady;
+	private boolean mFeedAboutToChange;
+	private boolean mPerformingLayoutChange;
+	private boolean mFeedChanged;
 
-    private Context mContext;
-    private RenderView mView;
-    private boolean mPickIntent;
-    private boolean mViewIntent;
-    private WakeLock mWakeLock;
-    private int mStartMemoryRange;
-    private int mFramesDirty;
-    private String mRequestFocusContentUri;
-    private int mFrameCount;
+	private final LayoutInterface mLayoutInterface;
+	private static final LayoutInterface sfullScreenLayoutInterface = new GridLayoutInterface(1);
 
-    public GridLayer(Context context, int itemWidth, int itemHeight, LayoutInterface layoutInterface, RenderView view) {
-        mBackground = new BackgroundLayer(this);
-        mContext = context;
-        mView = view;
-        
-        DisplaySlot[] displaySlots = sDisplaySlots;
-        for (int i = 0; i < MAX_DISPLAY_SLOTS; ++i) {
-            DisplaySlot slot = new DisplaySlot();
-            displaySlots[i] = slot;
-        }
-        mLayoutInterface = layoutInterface;
-        mCamera = new GridCamera(0, 0, itemWidth, itemHeight);
-        mDrawables = new GridDrawables(itemWidth, itemHeight);
-        sBufferedVisibleRange.set(Shared.INVALID, Shared.INVALID);
-        sVisibleRange.set(Shared.INVALID, Shared.INVALID);
-        sCompleteRange.set(Shared.INVALID, Shared.INVALID);
-        sPreviousDataRange.set(Shared.INVALID, Shared.INVALID);
-        sDeltaAnchorPosition.set(0, 0, 0);
-        sDeltaAnchorPositionUncommited.set(0, 0, 0);
-        sBucketList.clear();
-        
-        sVisibleItems = new ArrayList<MediaItem>();
-        if (sHud == null) {
-            sHud = new HudLayer(context);
-        }
-        sHud.setContext(context);
-        sHud.setGridLayer(this);
-        sHud.getPathBar().clear();
-        sHud.setGridLayer(this);
-        sHud.getTimeBar().setListener(this);
-        sHud.getPathBar().pushLabel(R.drawable.icon_home_small, context.getResources().getString(R.string.app_name),
-                new Runnable() {
-                    public void run() {
-                        if (sHud.getAlpha() == 1.0f) {
-                            if (!mFeedAboutToChange) {
-                                setState(STATE_MEDIA_SETS);
-                            }
-                        } else {
-                            sHud.setAlpha(1.0f);
-                        }
-                    }
-                });
-        mCameraManager = new GridCameraManager(mCamera);
-        mDrawManager = new GridDrawManager(context, mCamera, mDrawables, sDisplayList, sDisplayItems, sDisplaySlots);
-        mInputProcessor = new GridInputProcessor(context, mCamera, this, mView, sTempVec, sDisplayItems);
-        setState(STATE_MEDIA_SETS);
-    }
+	private MediaFeed mMediaFeed;
+	private boolean mInAlbum = false;
+	private int mCurrentExpandedSlot;
 
-    public HudLayer getHud() {
-        return sHud;
-    }
+	private static final DisplayList sDisplayList = new DisplayList();
+	private static final DisplayItem[] sDisplayItems = new DisplayItem[MAX_ITEMS_DRAWABLE];
+	private static final DisplaySlot[] sDisplaySlots = new DisplaySlot[MAX_DISPLAY_SLOTS];
+	private static ArrayList<MediaItem> sVisibleItems;
 
-    public void shutdown() {
-        if (mMediaFeed != null) {
-            mMediaFeed.shutdown();
-        }
-        mContext = null;
-        mBackground = null;
-        sBucketList.clear();
-        mCameraManager = null;
-        mDrawManager = null;
-        mView = null;
-    }
+	private float mTimeElapsedSinceTransition;
+	private BackgroundLayer mBackground;
+	private boolean mLocationFilter;
+	private float mZoomValue = 1.0f;
+	private float mCurrentFocusItemWidth = 1.0f;
+	private float mCurrentFocusItemHeight = 1.0f;
+	private float mTimeElapsedSinceGridViewReady = 0.0f;
 
-    public void stop() {
-        endSlideshow();
-        mBackground.clear();
-        handleLowMemory();
-    }
+	private boolean mSlideshowMode;
+	private boolean mNoDeleteMode = false;
+	private float mTimeElapsedSinceView;
+	private static final MediaBucketList sBucketList = new MediaBucketList();
+	private float mTimeElapsedSinceStackViewReady;
 
-    @Override
-    public void generate(RenderView view, RenderView.Lists lists) {
-        lists.updateList.add(this);
-        lists.opaqueList.add(this);
-        mBackground.generate(view, lists);
-        lists.blendedList.add(this);
-        lists.hitTestList.add(this);
-        sHud.generate(view, lists);
-    }
+	private Context mContext;
+	private RenderView mView;
+	private boolean mPickIntent;
+	private boolean mViewIntent;
+	private WakeLock mWakeLock;
+	private int mStartMemoryRange;
+	private int mFramesDirty;
+	private String mRequestFocusContentUri;
+	private int mFrameCount;
+	private boolean mNeedsInit;
 
-    @Override
-    protected void onSizeChanged() {
-        sHud.setSize(mWidth, mHeight);
-        sHud.setAlpha(1.0f);
-        mBackground.setSize(mWidth, mHeight);
-        mTimeElapsedSinceTransition = 0.0f;
-        if (mView != null) {
-            mView.requestRender();
-        }
-    }
+	public GridLayer(Context context, int itemWidth, int itemHeight, LayoutInterface layoutInterface, RenderView view) {
+		mBackground = new BackgroundLayer(this);
+		mContext = context;
+		mView = view;
+		mNeedsInit = true;
 
-    public int getState() {
-        return mState;
-    }
+		DisplaySlot[] displaySlots = sDisplaySlots;
+		for (int i = 0; i < MAX_DISPLAY_SLOTS; ++i) {
+			DisplaySlot slot = new DisplaySlot();
+			displaySlots[i] = slot;
+		}
+		mLayoutInterface = layoutInterface;
+		mCamera = new GridCamera(0, 0, itemWidth, itemHeight);
+		mDrawables = new GridDrawables(itemWidth, itemHeight);
+		sBufferedVisibleRange.set(Shared.INVALID, Shared.INVALID);
+		sVisibleRange.set(Shared.INVALID, Shared.INVALID);
+		sCompleteRange.set(Shared.INVALID, Shared.INVALID);
+		sPreviousDataRange.set(Shared.INVALID, Shared.INVALID);
+		sDeltaAnchorPosition.set(0, 0, 0);
+		sDeltaAnchorPositionUncommited.set(0, 0, 0);
+		sBucketList.clear();
 
-    public void setState(int state) {
-        boolean feedUnchanged = false;
-        if (mState == state) {
-            feedUnchanged = true;
-        }
-        GridLayoutInterface layoutInterface = (GridLayoutInterface) mLayoutInterface;
-        GridLayoutInterface oldLayout = (GridLayoutInterface) sfullScreenLayoutInterface;
-        oldLayout.mNumRows = layoutInterface.mNumRows;
-        oldLayout.mSpacingX = layoutInterface.mSpacingX;
-        oldLayout.mSpacingY = layoutInterface.mSpacingY;
-        GridCamera camera = mCamera;
-        int numMaxRows = (camera.mHeight >= camera.mWidth) ? 4 : 3;
-        MediaFeed feed = mMediaFeed;
-        boolean performLayout = true;
-        mZoomValue = 1.0f;
-        float yStretch = camera.mDefaultAspectRatio / camera.mAspectRatio;
-        if (yStretch < 1.0f) {
-            yStretch = 1.0f;
-        }
-        switch (state) {
-        case STATE_GRID_VIEW:
-            mTimeElapsedSinceGridViewReady = 0.0f;
-            if (feed != null && feedUnchanged == false) {
-                boolean updatedData = feed.restorePreviousClusteringState();
-                if (updatedData) {
-                    performLayout = false;
-                }
-            }
-            layoutInterface.mNumRows = numMaxRows;
-            layoutInterface.mSpacingX = (int) (10 * Gallery.PIXEL_DENSITY);
-            layoutInterface.mSpacingY = (int) (10 * Gallery.PIXEL_DENSITY);
-            if (mState == STATE_MEDIA_SETS) {
-                // Entering album.
-                mInAlbum = true;
-                MediaSet set = feed.getCurrentSet();
-                int icon = mDrawables.getIconForSet(set, true);
-                if (set != null) {
-                    sHud.getPathBar().pushLabel(icon, set.mNoCountTitleString, new Runnable() {
-                        public void run() {
-                            if (mFeedAboutToChange) {
-                                return;
-                            }
-                            if (sHud.getAlpha() == 1.0f) {
-                                disableLocationFiltering();
-                                mInputProcessor.clearSelection();
-                                setState(STATE_GRID_VIEW);
-                            } else {
-                                sHud.setAlpha(1.0f);
-                            }
-                        }
-                    });
-                }
-            }
-            if (mState == STATE_FULL_SCREEN) {
-                sHud.getPathBar().popLabel();
-            }
-            break;
-        case STATE_TIMELINE:
-            mTimeElapsedSinceStackViewReady = 0.0f;
-            if (feed != null && feedUnchanged == false) {
-                feed.performClustering();
-                performLayout = false;
-            }
-            disableLocationFiltering();
-            layoutInterface.mNumRows = numMaxRows - 1;
-            layoutInterface.mSpacingX = (int) (100 * Gallery.PIXEL_DENSITY);
-            layoutInterface.mSpacingY = (int) (70 * Gallery.PIXEL_DENSITY * yStretch);
-            break;
-        case STATE_FULL_SCREEN:
-            layoutInterface.mNumRows = 1;
-            layoutInterface.mSpacingX = (int) (40 * Gallery.PIXEL_DENSITY);
-            layoutInterface.mSpacingY = (int) (40 * Gallery.PIXEL_DENSITY);
-            if (mState != STATE_FULL_SCREEN) {
-                sHud.getPathBar().pushLabel(R.drawable.ic_fs_details, "", new Runnable() {
-                    public void run() {
-                        if (sHud.getAlpha() == 1.0f) {
-                            sHud.swapFullscreenLabel();
-                        }
-                        sHud.setAlpha(1.0f);
-                    }
-                });
-            }
-            break;
-        case STATE_MEDIA_SETS:
-            mTimeElapsedSinceStackViewReady = 0.0f;
-            if (feed != null && feedUnchanged == false) {
-                feed.restorePreviousClusteringState();
-                feed.expandMediaSet(Shared.INVALID);
-                performLayout = false;
-            }
-            disableLocationFiltering();
-            mInputProcessor.clearSelection();
-            layoutInterface.mNumRows = numMaxRows - 1;
-            layoutInterface.mSpacingX = (int) (100 * Gallery.PIXEL_DENSITY);
-            layoutInterface.mSpacingY = (int) (70 * Gallery.PIXEL_DENSITY * yStretch);
-            if (mInAlbum) {
-                if (mState == STATE_FULL_SCREEN) {
-                    sHud.getPathBar().popLabel();
-                }
-                sHud.getPathBar().popLabel();
-                mInAlbum = false;
-            }
-            break;
-        }
-        mState = state;
-        sHud.onGridStateChanged();
-        if (performLayout && mFeedAboutToChange == false) {
-            onLayout(Shared.INVALID, Shared.INVALID, oldLayout);
-        }
-        if (state != STATE_FULL_SCREEN) {
-            mCamera.moveYTo(0);
-            mCamera.moveZTo(0);
-        }
-    }
+		sVisibleItems = new ArrayList<MediaItem>();
+		if (sHud == null) {
+			sHud = new HudLayer(context);
+		}
+		sHud.setContext(context);
+		sHud.setGridLayer(this);
+		sHud.getPathBar().clear();
+		sHud.setGridLayer(this);
+		sHud.getTimeBar().setListener(this);
+		sHud.getPathBar().pushLabel(R.drawable.icon_home_small, context.getResources().getString(R.string.app_name),
+		        new Runnable() {
+			        public void run() {
+				        if (sHud.getAlpha() == 1.0f) {
+					        if (!mFeedAboutToChange) {
+						        setState(STATE_MEDIA_SETS);
+					        }
+				        } else {
+					        sHud.setAlpha(1.0f);
+				        }
+			        }
+		        });
+		mCameraManager = new GridCameraManager(mCamera);
+		mDrawManager = new GridDrawManager(context, mCamera, mDrawables, sDisplayList, sDisplayItems, sDisplaySlots);
+		mInputProcessor = new GridInputProcessor(context, mCamera, this, mView, sTempVec, sDisplayItems);
+	}
 
-    protected void enableLocationFiltering(String label) {
-        if (mLocationFilter == false) {
-            mLocationFilter = true;
-            sHud.getPathBar().pushLabel(R.drawable.icon_location_small, label, new Runnable() {
-                public void run() {
-                    if (sHud.getAlpha() == 1.0f) {
-                        if (mState == STATE_FULL_SCREEN) {
-                            mInputProcessor.clearSelection();
-                            setState(STATE_GRID_VIEW);
-                        } else {
-                            disableLocationFiltering();
-                        }
-                    } else {
-                        sHud.setAlpha(1.0f);
-                    }
-                }
-            });
-        }
-    }
+	public HudLayer getHud() {
+		return sHud;
+	}
 
-    protected void disableLocationFiltering() {
-        if (mLocationFilter) {
-            mLocationFilter = false;
-            mMediaFeed.removeFilter();
-            sHud.getPathBar().popLabel();
-        }
-    }
+	public void shutdown() {
+		if (mMediaFeed != null) {
+			mMediaFeed.shutdown();
+		}
+		mContext = null;
+		mBackground = null;
+		sBucketList.clear();
+		mView = null;
+	}
 
-    boolean goBack() {
-        if (mFeedAboutToChange) {
-            return false;
-        }
-        int state = mState;
-        if (mInputProcessor.getCurrentSelectedSlot() == Shared.INVALID) {
-            if (mLocationFilter) {
-                disableLocationFiltering();
-                setState(STATE_TIMELINE);
-                return true;
-            }
-        }
-        switch (state) {
-        case STATE_GRID_VIEW:
-            setState(STATE_MEDIA_SETS);
-            break;
-        case STATE_TIMELINE:
-            setState(STATE_GRID_VIEW);
-            break;
-        case STATE_FULL_SCREEN:
-            setState(STATE_GRID_VIEW);
-            mInputProcessor.clearSelection();
-            break;
-        default:
-            return false;
-        }
-        return true;
-    }
+	public void stop() {
+		endSlideshow();
+		mBackground.clear();
+		handleLowMemory();
+	}
 
-    public void endSlideshow() {
-        mSlideshowMode = false;
-        if (mWakeLock != null) {
-            if (mWakeLock.isHeld()) {
-                mWakeLock.release();
-            }
-            mWakeLock = null;
-        }
-        sHud.setAlpha(1.0f);
-    }
+	@Override
+	public void generate(RenderView view, RenderView.Lists lists) {
+		lists.updateList.add(this);
+		lists.opaqueList.add(this);
+		mBackground.generate(view, lists);
+		lists.blendedList.add(this);
+		lists.hitTestList.add(this);
+		sHud.generate(view, lists);
+	}
 
-    @Override
-    public void onSensorChanged(RenderView view, SensorEvent event) {
-        mInputProcessor.onSensorChanged(view, event, mState);
-    }
+	@Override
+	protected void onSizeChanged() {
+		sHud.setSize(mWidth, mHeight);
+		sHud.setAlpha(1.0f);
+		mBackground.setSize(mWidth, mHeight);
+		mTimeElapsedSinceTransition = 0.0f;
+		if (mView != null) {
+			mView.requestRender();
+		}
+	}
 
-    public DataSource getDataSource() {
-        if (mMediaFeed != null)
-            return mMediaFeed.getDataSource();
-        return null;
-    }
+	public int getState() {
+		return mState;
+	}
 
-    public void setDataSource(DataSource dataSource) {
-        MediaFeed feed = mMediaFeed;
-        if (feed != null) {
-            feed.shutdown();
-            sDisplayList.clear();
-            mBackground.clear();
-        }
-        mMediaFeed = new MediaFeed(mContext, dataSource, this);
-        mMediaFeed.start();
-    }
+	public void setState(int state) {
+		boolean feedUnchanged = false;
+		if (mState == state) {
+			feedUnchanged = true;
+		}
+		GridLayoutInterface layoutInterface = (GridLayoutInterface) mLayoutInterface;
+		GridLayoutInterface oldLayout = (GridLayoutInterface) sfullScreenLayoutInterface;
+		oldLayout.mNumRows = layoutInterface.mNumRows;
+		oldLayout.mSpacingX = layoutInterface.mSpacingX;
+		oldLayout.mSpacingY = layoutInterface.mSpacingY;
+		GridCamera camera = mCamera;
+		int numMaxRows = (camera.mHeight >= camera.mWidth) ? 4 : 3;
+		MediaFeed feed = mMediaFeed;
+		boolean performLayout = true;
+		mZoomValue = 1.0f;
+		float yStretch = camera.mDefaultAspectRatio / camera.mAspectRatio;
+		if (yStretch < 1.0f) {
+			yStretch = 1.0f;
+		}
+		switch (state) {
+		case STATE_GRID_VIEW:
+			mTimeElapsedSinceGridViewReady = 0.0f;
+			if (feed != null && feedUnchanged == false) {
+				boolean updatedData = feed.restorePreviousClusteringState();
+				if (updatedData) {
+					performLayout = false;
+				}
+			}
+			layoutInterface.mNumRows = numMaxRows;
+			layoutInterface.mSpacingX = (int) (10 * Gallery.PIXEL_DENSITY);
+			layoutInterface.mSpacingY = (int) (10 * Gallery.PIXEL_DENSITY);
+			if (mState == STATE_MEDIA_SETS) {
+				// Entering album.
+				mInAlbum = true;
+				MediaSet set = feed.getCurrentSet();
+				int icon = mDrawables.getIconForSet(set, true);
+				if (set != null) {
+					sHud.getPathBar().pushLabel(icon, set.mNoCountTitleString, new Runnable() {
+						public void run() {
+							if (mFeedAboutToChange) {
+								return;
+							}
+							if (sHud.getAlpha() == 1.0f) {
+								disableLocationFiltering();
+								mInputProcessor.clearSelection();
+								setState(STATE_GRID_VIEW);
+							} else {
+								sHud.setAlpha(1.0f);
+							}
+						}
+					});
+				}
+			}
+			if (mState == STATE_FULL_SCREEN) {
+				sHud.getPathBar().popLabel();
+			}
+			break;
+		case STATE_TIMELINE:
+			mTimeElapsedSinceStackViewReady = 0.0f;
+			if (feed != null && feedUnchanged == false) {
+				feed.performClustering();
+				performLayout = false;
+			}
+			disableLocationFiltering();
+			layoutInterface.mNumRows = numMaxRows - 1;
+			layoutInterface.mSpacingX = (int) (100 * Gallery.PIXEL_DENSITY);
+			layoutInterface.mSpacingY = (int) (70 * Gallery.PIXEL_DENSITY * yStretch);
+			break;
+		case STATE_FULL_SCREEN:
+			layoutInterface.mNumRows = 1;
+			layoutInterface.mSpacingX = (int) (40 * Gallery.PIXEL_DENSITY);
+			layoutInterface.mSpacingY = (int) (40 * Gallery.PIXEL_DENSITY);
+			if (mState != STATE_FULL_SCREEN) {
+				sHud.getPathBar().pushLabel(R.drawable.ic_fs_details, "", new Runnable() {
+					public void run() {
+						if (sHud.getAlpha() == 1.0f) {
+							sHud.swapFullscreenLabel();
+						}
+						sHud.setAlpha(1.0f);
+					}
+				});
+			}
+			break;
+		case STATE_MEDIA_SETS:
+			mTimeElapsedSinceStackViewReady = 0.0f;
+			if (feed != null && feedUnchanged == false) {
+				feed.restorePreviousClusteringState();
+				feed.expandMediaSet(Shared.INVALID);
+				performLayout = false;
+			}
+			disableLocationFiltering();
+			mInputProcessor.clearSelection();
+			layoutInterface.mNumRows = numMaxRows - 1;
+			layoutInterface.mSpacingX = (int) (100 * Gallery.PIXEL_DENSITY);
+			layoutInterface.mSpacingY = (int) (70 * Gallery.PIXEL_DENSITY * yStretch);
+			if (mInAlbum) {
+				if (mState == STATE_FULL_SCREEN) {
+					sHud.getPathBar().popLabel();
+				}
+				sHud.getPathBar().popLabel();
+				mInAlbum = false;
+			}
+			break;
+		}
+		mState = state;
+		sHud.onGridStateChanged();
+		if (performLayout && mFeedAboutToChange == false) {
+			onLayout(Shared.INVALID, Shared.INVALID, oldLayout);
+		}
+		if (state != STATE_FULL_SCREEN) {
+			mCamera.moveYTo(0);
+			mCamera.moveZTo(0);
+		}
+	}
 
-    public IndexRange getVisibleRange() {
-        return sVisibleRange;
-    }
+	protected void enableLocationFiltering(String label) {
+		if (mLocationFilter == false) {
+			mLocationFilter = true;
+			sHud.getPathBar().pushLabel(R.drawable.icon_location_small, label, new Runnable() {
+				public void run() {
+					if (sHud.getAlpha() == 1.0f) {
+						if (mState == STATE_FULL_SCREEN) {
+							mInputProcessor.clearSelection();
+							setState(STATE_GRID_VIEW);
+						} else {
+							disableLocationFiltering();
+						}
+					} else {
+						sHud.setAlpha(1.0f);
+					}
+				}
+			});
+		}
+	}
 
-    public IndexRange getBufferedVisibleRange() {
-        return sBufferedVisibleRange;
-    }
+	protected void disableLocationFiltering() {
+		if (mLocationFilter) {
+			mLocationFilter = false;
+			mMediaFeed.removeFilter();
+			sHud.getPathBar().popLabel();
+		}
+	}
 
-    public IndexRange getCompleteRange() {
-        return sCompleteRange;
-    }
+	boolean goBack() {
+		if (mFeedAboutToChange) {
+			return false;
+		}
+		int state = mState;
+		if (mInputProcessor.getCurrentSelectedSlot() == Shared.INVALID) {
+			if (mLocationFilter) {
+				disableLocationFiltering();
+				setState(STATE_TIMELINE);
+				return true;
+			}
+		}
+		switch (state) {
+		case STATE_GRID_VIEW:
+			setState(STATE_MEDIA_SETS);
+			break;
+		case STATE_TIMELINE:
+			setState(STATE_GRID_VIEW);
+			break;
+		case STATE_FULL_SCREEN:
+			setState(STATE_GRID_VIEW);
+			mInputProcessor.clearSelection();
+			break;
+		default:
+			return false;
+		}
+		return true;
+	}
 
-    private int hitTest(Vector3f worldPos, int itemWidth, int itemHeight) {
-        int retVal = Shared.INVALID;
-        int firstSlotIndex = 0;
-        int lastSlotIndex = 0;
-        IndexRange rangeToUse = sVisibleRange;
-        synchronized (rangeToUse) {
-            firstSlotIndex = rangeToUse.begin;
-            lastSlotIndex = rangeToUse.end;
-        }
-        Pool<Vector3f> pool = sTempVec;
-        float itemWidthBy2 = itemWidth * 0.5f;
-        float itemHeightBy2 = itemHeight * 0.5f;
-        Vector3f position = pool.create();
-        Vector3f deltaAnchorPosition = pool.create();
-        try {
-            deltaAnchorPosition.set(sDeltaAnchorPosition);
-            for (int i = firstSlotIndex; i <= lastSlotIndex; ++i) {
-                GridCameraManager.getSlotPositionForSlotIndex(i, mCamera, mLayoutInterface, deltaAnchorPosition, position);
-                if (FloatUtils.boundsContainsPoint(position.x - itemWidthBy2, position.x + itemWidthBy2,
-                        position.y - itemHeightBy2, position.y + itemHeightBy2, worldPos.x, worldPos.y)) {
-                    retVal = i;
-                    break;
-                }
-            }
-        } finally {
-            pool.delete(deltaAnchorPosition);
-            pool.delete(position);
-        }
-        return retVal;
-    }
+	public void endSlideshow() {
+		mSlideshowMode = false;
+		if (mWakeLock != null) {
+			if (mWakeLock.isHeld()) {
+				mWakeLock.release();
+			}
+			mWakeLock = null;
+		}
+		sHud.setAlpha(1.0f);
+	}
 
-    void centerCameraForSlot(int slotIndex, float baseConvergence) {
-        float imageTheta = 0.0f;
-        DisplayItem displayItem = getDisplayItemForSlotId(slotIndex);
-        if (displayItem != null) {
-            imageTheta = displayItem.getImageTheta();
-        }
-        mCameraManager.centerCameraForSlot(mLayoutInterface, slotIndex, baseConvergence, sDeltaAnchorPositionUncommited,
-                mInputProcessor.getCurrentSelectedSlot(), mZoomValue, imageTheta, mState);
-    }
+	@Override
+	public void onSensorChanged(RenderView view, SensorEvent event) {
+		mInputProcessor.onSensorChanged(view, event, mState);
+	}
 
-    boolean constrainCameraForSlot(int slotIndex) {
-        return mCameraManager.constrainCameraForSlot(mLayoutInterface, slotIndex, sDeltaAnchorPosition, mCurrentFocusItemWidth,
-                mCurrentFocusItemHeight);
-    }
+	public DataSource getDataSource() {
+		if (mMediaFeed != null)
+			return mMediaFeed.getDataSource();
+		return null;
+	}
 
-    // Called on render thread before rendering.
-    @Override
-    public boolean update(RenderView view, float timeElapsed) {
-        if (mFeedAboutToChange == false) {
-            mTimeElapsedSinceTransition += timeElapsed;
-            mTimeElapsedSinceGridViewReady += timeElapsed;
-            if (mTimeElapsedSinceGridViewReady >= 1.0f) {
-                mTimeElapsedSinceGridViewReady = 1.0f;
-            }
-            mTimeElapsedSinceStackViewReady += timeElapsed;
-            if (mTimeElapsedSinceStackViewReady >= 1.0f) {
-                mTimeElapsedSinceStackViewReady = 1.0f;
-            }
-        } else {
-            mTimeElapsedSinceTransition = 0;
-        }
-        if (mMediaFeed != null && mMediaFeed.isSingleImageMode()) {
-            HudLayer hud = getHud();
-            hud.getPathBar().setHidden(true);
-            hud.getMenuBar().setHidden(true);
-            if (hud.getMode() != HudLayer.MODE_NORMAL)
-                hud.setMode(HudLayer.MODE_NORMAL);
-        }
-        if (view.elapsedLoadingExpensiveTextures() > 150 || (mMediaFeed != null && mMediaFeed.getWaitingForMediaScanner())) {
-            sHud.getPathBar().setAnimatedIcons(GridDrawables.TEXTURE_SPINNER);
-        } else {
-            sHud.getPathBar().setAnimatedIcons(null);
-        }
+	public void setDataSource(DataSource dataSource) {
+		MediaFeed feed = mMediaFeed;
+		if (feed != null) {
+			feed.shutdown();
+			sDisplayList.clear();
+			mBackground.clear();
+		}
+		mMediaFeed = new MediaFeed(mContext, dataSource, this);
+		mMediaFeed.start();
+	}
 
-        // In that case, we need to commit the respective Display Items when the
-        // feed was updated.
-        GridCamera camera = mCamera;
-        camera.update(timeElapsed);
-        DisplayItem anchorDisplayItem = getAnchorDisplayItem(ANCHOR_CENTER);
-        if (anchorDisplayItem != null && !sHud.getTimeBar().isDragged()) {
-            sHud.getTimeBar().setItem(anchorDisplayItem.mItemRef);
-        }
-        sDisplayList.update(timeElapsed);
-        mInputProcessor.update(timeElapsed);
-        mSelectedAlpha = FloatUtils.animate(mSelectedAlpha, mTargetAlpha, timeElapsed * 0.5f);
-        if (mState == STATE_FULL_SCREEN) {
-            sHud.autoHide(true);
-        } else {
-            sHud.autoHide(false);
-            sHud.setAlpha(1.0f);
-        }
-        GridQuad[] fullscreenQuads = GridDrawables.sFullscreenGrid;
-        int numFullScreenQuads = fullscreenQuads.length;
-        for (int i = 0; i < numFullScreenQuads; ++i) {
-            fullscreenQuads[i].update(timeElapsed);
-        }
-        if (mSlideshowMode && mState == STATE_FULL_SCREEN) {
-            mTimeElapsedSinceView += timeElapsed;
-            if (mTimeElapsedSinceView > SLIDESHOW_TRANSITION_TIME) {
-                // time to go to the next slide
-                mTimeElapsedSinceView = 0.0f;
-                changeFocusToNextSlot(0.5f);
-                mCamera.commitMoveInX();
-                mCamera.commitMoveInY();
-            }
-        }
-        if (mState == STATE_MEDIA_SETS || mState == STATE_TIMELINE) {
-            mCamera.moveYTo(-0.1f);
-            mCamera.commitMoveInY();
-        }
-        boolean dirty = mDrawManager.update(timeElapsed);
-        dirty |= mSlideshowMode;
-        dirty |= mFramesDirty > 0;
-        ++mFrameCount;
-        if (mFramesDirty > 0) {
-            --mFramesDirty;
-        }
-        try {
-            if (mMediaFeed != null && (mMediaFeed.getWaitingForMediaScanner())) {
-                // We limit the drawing of the frame so that the MediaScanner thread can do its work
-                Thread.sleep(200);
-            }
-        } catch (InterruptedException e) {
+	public IndexRange getVisibleRange() {
+		return sVisibleRange;
+	}
 
-        }
-        if (sDisplayList.getNumAnimatables() != 0 || mCamera.isAnimating()
-                || (mTimeElapsedSinceTransition > 0.0f && mTimeElapsedSinceTransition < 1.0f) || mSelectedAlpha != mTargetAlpha
-                // || (mAnimatedFov != mTargetFov)
-                || dirty)
-            return true;
-        else
-            return false;
-    }
+	public IndexRange getBufferedVisibleRange() {
+		return sBufferedVisibleRange;
+	}
 
-    private void computeVisibleRange() {
-        if (mPerformingLayoutChange)
-            return;
-        if (sDeltaAnchorPosition.equals(sDeltaAnchorPositionUncommited) == false) {
-            sDeltaAnchorPosition.set(sDeltaAnchorPositionUncommited);
-        }
-        mCameraManager.computeVisibleRange(mMediaFeed, mLayoutInterface, sDeltaAnchorPosition, sVisibleRange,
-                sBufferedVisibleRange, sCompleteRange, mState);
-    }
+	public IndexRange getCompleteRange() {
+		return sCompleteRange;
+	}
 
-    private void computeVisibleItems() {
-        if (mFeedAboutToChange == true || mPerformingLayoutChange == true) {
-            return;
-        }
-        computeVisibleRange();
-        int deltaBegin = sBufferedVisibleRange.begin - sPreviousDataRange.begin;
-        int deltaEnd = sBufferedVisibleRange.end - sPreviousDataRange.end;
-        if (deltaBegin != 0 || deltaEnd != 0) {
-            // The delta has changed, we have to compute the display items again.
-            // We find the intersection range, these slots have not changed at all.
-            int firstVisibleSlotIndex = sBufferedVisibleRange.begin;
-            int lastVisibleSlotIndex = sBufferedVisibleRange.end;
-            sPreviousDataRange.begin = firstVisibleSlotIndex;
-            sPreviousDataRange.end = lastVisibleSlotIndex;
+	private int hitTest(Vector3f worldPos, int itemWidth, int itemHeight) {
+		int retVal = Shared.INVALID;
+		int firstSlotIndex = 0;
+		int lastSlotIndex = 0;
+		IndexRange rangeToUse = sVisibleRange;
+		synchronized (rangeToUse) {
+			firstSlotIndex = rangeToUse.begin;
+			lastSlotIndex = rangeToUse.end;
+		}
+		Pool<Vector3f> pool = sTempVec;
+		float itemWidthBy2 = itemWidth * 0.5f;
+		float itemHeightBy2 = itemHeight * 0.5f;
+		Vector3f position = pool.create();
+		Vector3f deltaAnchorPosition = pool.create();
+		try {
+			deltaAnchorPosition.set(sDeltaAnchorPosition);
+			for (int i = firstSlotIndex; i <= lastSlotIndex; ++i) {
+				GridCameraManager.getSlotPositionForSlotIndex(i, mCamera, mLayoutInterface, deltaAnchorPosition, position);
+				if (FloatUtils.boundsContainsPoint(position.x - itemWidthBy2, position.x + itemWidthBy2,
+				        position.y - itemHeightBy2, position.y + itemHeightBy2, worldPos.x, worldPos.y)) {
+					retVal = i;
+					break;
+				}
+			}
+		} finally {
+			pool.delete(deltaAnchorPosition);
+			pool.delete(position);
+		}
+		return retVal;
+	}
 
-            Pool<Vector3f> pool = sTempVec;
-            Vector3f position = pool.create();
-            Vector3f deltaAnchorPosition = pool.create();
-            try {
-                MediaFeed feed = mMediaFeed;
-                DisplayList displayList = sDisplayList;
-                DisplayItem[] displayItems = sDisplayItems;
-                DisplaySlot[] displaySlots = sDisplaySlots;
-                int numDisplayItems = displayItems.length;
-                int numDisplaySlots = displaySlots.length;
-                ArrayList<MediaItem> visibleItems = sVisibleItems;
-                deltaAnchorPosition.set(sDeltaAnchorPosition);
-                LayoutInterface layout = mLayoutInterface;
-                GridCamera camera = mCamera;
-                for (int i = firstVisibleSlotIndex; i <= lastVisibleSlotIndex; ++i) {
-                    GridCameraManager.getSlotPositionForSlotIndex(i, camera, layout, deltaAnchorPosition, position);
-                    MediaSet set = feed.getSetForSlot(i);
-                    int indexIntoSlots = i - firstVisibleSlotIndex;
+	void centerCameraForSlot(int slotIndex, float baseConvergence) {
+		float imageTheta = 0.0f;
+		DisplayItem displayItem = getDisplayItemForSlotId(slotIndex);
+		if (displayItem != null) {
+			imageTheta = displayItem.getImageTheta();
+		}
+		mCameraManager.centerCameraForSlot(mLayoutInterface, slotIndex, baseConvergence, sDeltaAnchorPositionUncommited,
+		        mInputProcessor.getCurrentSelectedSlot(), mZoomValue, imageTheta, mState);
+	}
 
-                    if (set != null && indexIntoSlots >= 0 && indexIntoSlots < numDisplaySlots) {
-                        ArrayList<MediaItem> items = set.getItems();
-                        displaySlots[indexIntoSlots].setMediaSet(set);
-                        ArrayList<MediaItem> bestItems = sTempList;
-                        if (mTimeElapsedSinceTransition < 1.0f) {
-                            // We always show the same top thumbnails for a stack of albums
-                            if (mState == STATE_MEDIA_SETS)
-                                ArrayUtils.computeSortedIntersection(items, visibleItems, MAX_ITEMS_PER_SLOT, bestItems, sTempHash);
-                            else
-                                ArrayUtils.computeSortedIntersection(visibleItems, items, MAX_ITEMS_PER_SLOT, bestItems, sTempHash);
-                        }
-                        
-                        int numItemsInSet = set.getNumItems();
-                        int numBestItems = bestItems.size();
-                        int originallyFoundItems = numBestItems;
-                        if (numBestItems < MAX_ITEMS_PER_SLOT) {
-                            int itemsRemaining = MAX_ITEMS_PER_SLOT - numBestItems;
-                            for (int currItemPos = 0; currItemPos < numItemsInSet; currItemPos++) {
-                                MediaItem item = items.get(currItemPos);
-                                if (mTimeElapsedSinceTransition >= 1.0f || !bestItems.contains(item)) {
-                                    bestItems.add(item);
-                                    if (--itemsRemaining == 0) {
-                                        break;
-                                    }
-                                }
-                            }
-                        }
-                        numBestItems = bestItems.size();
-                        int baseIndex = (i - firstVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
-                        for (int j = 0; j < numBestItems; ++j) {
-                            if (baseIndex + j >= numDisplayItems) {
-                                break;
-                            }
-                            if (j >= numItemsInSet) {
-                                displayItems[baseIndex + j] = null;
-                            } else {
-                                MediaItem item = bestItems.get(j);
-                                if (item != null) {
-                                    DisplayItem displayItem = displayList.get(item);
-                                    if ((mState == STATE_FULL_SCREEN && i != mInputProcessor.getCurrentSelectedSlot())
-                                            || (mState == STATE_GRID_VIEW && (mTimeElapsedSinceTransition > 1.0f || j >= originallyFoundItems))) {
-                                        displayItem.set(position, j, false);
-                                        displayItem.commit();
-                                    } else {
-                                        displayList.setPositionAndStackIndex(displayItem, position, j, true);
-                                    }
-                                    displayItems[baseIndex + j] = displayItem;
-                                }
-                            }
-                        }
-                        for (int j = numBestItems; j < MAX_ITEMS_PER_SLOT; ++j) {
-                            displayItems[baseIndex + j] = null;
-                        }
-                        bestItems.clear();
-                    }
-                }
-                if (mFeedChanged) {
-                    mFeedChanged = false;
-                    if (mInputProcessor != null && mState == STATE_FULL_SCREEN) {
-                        int currentSelectedSlot = mInputProcessor.getCurrentSelectedSlot();
-                        if (currentSelectedSlot > sCompleteRange.end)
-                            currentSelectedSlot = sCompleteRange.end;
-                        mInputProcessor.setCurrentSelectedSlot(currentSelectedSlot);
-                    }
-                    if (mState == STATE_GRID_VIEW) {
-                        MediaSet expandedSet = mMediaFeed.getExpandedMediaSet();
-                        if (expandedSet != null) {
-                            if (!sHud.getPathBar().getCurrentLabel().equals(expandedSet.mNoCountTitleString)) {
-                                sHud.getPathBar().changeLabel(expandedSet.mNoCountTitleString);
-                            }
-                        }
-                    }
-                    if (mRequestFocusContentUri != null) {
-                        // We have to find the item that has this contentUri
-                        if (mState == STATE_FULL_SCREEN) {
-                            int numSlots = sCompleteRange.end;
-                            for (int i = 0; i < numSlots; ++i) {
-                                MediaSet set = feed.getSetForSlot(i);
-                                ArrayList<MediaItem> items = set.getItems();
-                                int numItems = items.size();
-                                for (int j = 0; j < numItems; ++j) {
-                                    if (items.get(j).mContentUri.equals(mRequestFocusContentUri)) {
-                                        mInputProcessor.setCurrentSelectedSlot(i);
-                                        break;
-                                    }
-                                }
-                            }
-                        }
-                        mRequestFocusContentUri = null;
-                    }
-                }
-            } finally {
-                pool.delete(position);
-                pool.delete(deltaAnchorPosition);
-            }
-            // We keep upto 400 thumbnails in memory.
-            int numThumbnailsToKeepInMemory = (mState == STATE_MEDIA_SETS || mState == STATE_TIMELINE) ? 100 : 400;
-            int startMemoryRange = (sBufferedVisibleRange.begin / numThumbnailsToKeepInMemory) * numThumbnailsToKeepInMemory;
-            if (mStartMemoryRange != startMemoryRange) {
-                mStartMemoryRange = startMemoryRange;
-                clearUnusedThumbnails();
-            }
-        }
-    }
+	boolean constrainCameraForSlot(int slotIndex) {
+		return mCameraManager.constrainCameraForSlot(mLayoutInterface, slotIndex, sDeltaAnchorPosition, mCurrentFocusItemWidth,
+		        mCurrentFocusItemHeight);
+	}
+
+	// Called on render thread before rendering.
+	@Override
+	public boolean update(RenderView view, float timeElapsed) {
+		if (mFeedAboutToChange == false) {
+			mTimeElapsedSinceTransition += timeElapsed;
+			mTimeElapsedSinceGridViewReady += timeElapsed;
+			if (mTimeElapsedSinceGridViewReady >= 1.0f) {
+				mTimeElapsedSinceGridViewReady = 1.0f;
+			}
+			mTimeElapsedSinceStackViewReady += timeElapsed;
+			if (mTimeElapsedSinceStackViewReady >= 1.0f) {
+				mTimeElapsedSinceStackViewReady = 1.0f;
+			}
+		} else {
+			mTimeElapsedSinceTransition = 0;
+		}
+		if (mMediaFeed != null && mMediaFeed.isSingleImageMode()) {
+			HudLayer hud = getHud();
+			hud.getPathBar().setHidden(true);
+			hud.getMenuBar().setHidden(true);
+			if (hud.getMode() != HudLayer.MODE_NORMAL)
+				hud.setMode(HudLayer.MODE_NORMAL);
+		}
+		if (view.elapsedLoadingExpensiveTextures() > 150 || (mMediaFeed != null && mMediaFeed.getWaitingForMediaScanner())) {
+			sHud.getPathBar().setAnimatedIcons(GridDrawables.TEXTURE_SPINNER);
+		} else {
+			sHud.getPathBar().setAnimatedIcons(null);
+		}
+
+		// In that case, we need to commit the respective Display Items when the
+		// feed was updated.
+		GridCamera camera = mCamera;
+		camera.update(timeElapsed);
+		DisplayItem anchorDisplayItem = getAnchorDisplayItem(ANCHOR_CENTER);
+		if (anchorDisplayItem != null && !sHud.getTimeBar().isDragged()) {
+			sHud.getTimeBar().setItem(anchorDisplayItem.mItemRef);
+		}
+		sDisplayList.update(timeElapsed);
+		mInputProcessor.update(timeElapsed);
+		mSelectedAlpha = FloatUtils.animate(mSelectedAlpha, mTargetAlpha, timeElapsed * 0.5f);
+		if (mState == STATE_FULL_SCREEN) {
+			sHud.autoHide(true);
+		} else {
+			sHud.autoHide(false);
+			sHud.setAlpha(1.0f);
+		}
+		GridQuad[] fullscreenQuads = GridDrawables.sFullscreenGrid;
+		int numFullScreenQuads = fullscreenQuads.length;
+		for (int i = 0; i < numFullScreenQuads; ++i) {
+			fullscreenQuads[i].update(timeElapsed);
+		}
+		if (mSlideshowMode && mState == STATE_FULL_SCREEN) {
+			mTimeElapsedSinceView += timeElapsed;
+			if (mTimeElapsedSinceView > SLIDESHOW_TRANSITION_TIME) {
+				// time to go to the next slide
+				mTimeElapsedSinceView = 0.0f;
+				changeFocusToNextSlot(0.5f);
+				mCamera.commitMoveInX();
+				mCamera.commitMoveInY();
+			}
+		}
+		if (mState == STATE_MEDIA_SETS || mState == STATE_TIMELINE) {
+			mCamera.moveYTo(-0.1f);
+			mCamera.commitMoveInY();
+		}
+		boolean dirty = mDrawManager.update(timeElapsed);
+		dirty |= mSlideshowMode;
+		dirty |= mFramesDirty > 0;
+		++mFrameCount;
+		if (mFramesDirty > 0) {
+			--mFramesDirty;
+		}
+		try {
+			if (mMediaFeed != null && (mMediaFeed.getWaitingForMediaScanner())) {
+				// We limit the drawing of the frame so that the MediaScanner
+				// thread can do its work
+				Thread.sleep(200);
+			}
+		} catch (InterruptedException e) {
+
+		}
+		if (sDisplayList.getNumAnimatables() != 0 || mCamera.isAnimating()
+		        || (mTimeElapsedSinceTransition > 0.0f && mTimeElapsedSinceTransition < 1.0f) || mSelectedAlpha != mTargetAlpha
+		        // || (mAnimatedFov != mTargetFov)
+		        || dirty)
+			return true;
+		else
+			return false;
+	}
+
+	private void computeVisibleRange() {
+		if (mPerformingLayoutChange)
+			return;
+		if (sDeltaAnchorPosition.equals(sDeltaAnchorPositionUncommited) == false) {
+			sDeltaAnchorPosition.set(sDeltaAnchorPositionUncommited);
+		}
+		mCameraManager.computeVisibleRange(mMediaFeed, mLayoutInterface, sDeltaAnchorPosition, sVisibleRange,
+		        sBufferedVisibleRange, sCompleteRange, mState);
+	}
+
+	private void computeVisibleItems() {
+		if (mFeedAboutToChange == true || mPerformingLayoutChange == true) {
+			return;
+		}
+		computeVisibleRange();
+		int deltaBegin = sBufferedVisibleRange.begin - sPreviousDataRange.begin;
+		int deltaEnd = sBufferedVisibleRange.end - sPreviousDataRange.end;
+		if (deltaBegin != 0 || deltaEnd != 0) {
+			// The delta has changed, we have to compute the display items
+			// again.
+			// We find the intersection range, these slots have not changed at
+			// all.
+			int firstVisibleSlotIndex = sBufferedVisibleRange.begin;
+			int lastVisibleSlotIndex = sBufferedVisibleRange.end;
+			sPreviousDataRange.begin = firstVisibleSlotIndex;
+			sPreviousDataRange.end = lastVisibleSlotIndex;
+
+			Pool<Vector3f> pool = sTempVec;
+			Vector3f position = pool.create();
+			Vector3f deltaAnchorPosition = pool.create();
+			try {
+				MediaFeed feed = mMediaFeed;
+				DisplayList displayList = sDisplayList;
+				DisplayItem[] displayItems = sDisplayItems;
+				DisplaySlot[] displaySlots = sDisplaySlots;
+				int numDisplayItems = displayItems.length;
+				int numDisplaySlots = displaySlots.length;
+				ArrayList<MediaItem> visibleItems = sVisibleItems;
+				deltaAnchorPosition.set(sDeltaAnchorPosition);
+				LayoutInterface layout = mLayoutInterface;
+				GridCamera camera = mCamera;
+				for (int i = firstVisibleSlotIndex; i <= lastVisibleSlotIndex; ++i) {
+					GridCameraManager.getSlotPositionForSlotIndex(i, camera, layout, deltaAnchorPosition, position);
+					MediaSet set = feed.getSetForSlot(i);
+					int indexIntoSlots = i - firstVisibleSlotIndex;
+
+					if (set != null && indexIntoSlots >= 0 && indexIntoSlots < numDisplaySlots) {
+						ArrayList<MediaItem> items = set.getItems();
+						displaySlots[indexIntoSlots].setMediaSet(set);
+						ArrayList<MediaItem> bestItems = sTempList;
+						if (mTimeElapsedSinceTransition < 1.0f) {
+							// We always show the same top thumbnails for a
+							// stack of albums
+							if (mState == STATE_MEDIA_SETS)
+								ArrayUtils.computeSortedIntersection(items, visibleItems, MAX_ITEMS_PER_SLOT, bestItems, sTempHash);
+							else
+								ArrayUtils.computeSortedIntersection(visibleItems, items, MAX_ITEMS_PER_SLOT, bestItems, sTempHash);
+						}
+
+						int numItemsInSet = set.getNumItems();
+						int numBestItems = bestItems.size();
+						int originallyFoundItems = numBestItems;
+						if (numBestItems < MAX_ITEMS_PER_SLOT) {
+							int itemsRemaining = MAX_ITEMS_PER_SLOT - numBestItems;
+							for (int currItemPos = 0; currItemPos < numItemsInSet; currItemPos++) {
+								MediaItem item = items.get(currItemPos);
+								if (mTimeElapsedSinceTransition >= 1.0f || !bestItems.contains(item)) {
+									bestItems.add(item);
+									if (--itemsRemaining == 0) {
+										break;
+									}
+								}
+							}
+						}
+						numBestItems = bestItems.size();
+						int baseIndex = (i - firstVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
+						for (int j = 0; j < numBestItems; ++j) {
+							if (baseIndex + j >= numDisplayItems) {
+								break;
+							}
+							if (j >= numItemsInSet) {
+								displayItems[baseIndex + j] = null;
+							} else {
+								MediaItem item = bestItems.get(j);
+								if (item != null) {
+									DisplayItem displayItem = displayList.get(item);
+									if ((mState == STATE_FULL_SCREEN && i != mInputProcessor.getCurrentSelectedSlot())
+									        || (mState == STATE_GRID_VIEW && (mTimeElapsedSinceTransition > 1.0f || j >= originallyFoundItems))) {
+										displayItem.set(position, j, false);
+										displayItem.commit();
+									} else {
+										displayList.setPositionAndStackIndex(displayItem, position, j, true);
+									}
+									displayItems[baseIndex + j] = displayItem;
+								}
+							}
+						}
+						for (int j = numBestItems; j < MAX_ITEMS_PER_SLOT; ++j) {
+							displayItems[baseIndex + j] = null;
+						}
+						bestItems.clear();
+					}
+				}
+				if (mFeedChanged) {
+					mFeedChanged = false;
+					if (mInputProcessor != null && mState == STATE_FULL_SCREEN && mRequestFocusContentUri == null) {
+						int currentSelectedSlot = mInputProcessor.getCurrentSelectedSlot();
+						if (currentSelectedSlot > sCompleteRange.end)
+							currentSelectedSlot = sCompleteRange.end;
+						mInputProcessor.setCurrentSelectedSlot(currentSelectedSlot);
+					}
+					if (mState == STATE_GRID_VIEW) {
+						MediaSet expandedSet = mMediaFeed.getExpandedMediaSet();
+						if (expandedSet != null) {
+							if (!sHud.getPathBar().getCurrentLabel().equals(expandedSet.mNoCountTitleString)) {
+								sHud.getPathBar().changeLabel(expandedSet.mNoCountTitleString);
+							}
+						}
+					}
+					if (mRequestFocusContentUri != null) {
+						// We have to find the item that has this contentUri
+						if (mState == STATE_FULL_SCREEN) {
+							int numSlots = sCompleteRange.end + 1;
+							for (int i = 0; i < numSlots; ++i) {
+								MediaSet set = feed.getSetForSlot(i);
+								ArrayList<MediaItem> items = set.getItems();
+								int numItems = items.size();
+								for (int j = 0; j < numItems; ++j) {
+									String itemUri = items.get(j).mContentUri;
+									if (itemUri != null && mRequestFocusContentUri != null) {
+										if (itemUri.equals(mRequestFocusContentUri)) {
+											mInputProcessor.setCurrentSelectedSlot(i);
+											mRequestFocusContentUri = null;
+											break;
+										}
+									}
+								}
+							}
+						}
+					}
+				}
+			} finally {
+				pool.delete(position);
+				pool.delete(deltaAnchorPosition);
+			}
+			// We keep upto 400 thumbnails in memory.
+			int numThumbnailsToKeepInMemory = (mState == STATE_MEDIA_SETS || mState == STATE_TIMELINE) ? 100 : 400;
+			int startMemoryRange = (sBufferedVisibleRange.begin / numThumbnailsToKeepInMemory) * numThumbnailsToKeepInMemory;
+			if (mStartMemoryRange != startMemoryRange) {
+				mStartMemoryRange = startMemoryRange;
+				clearUnusedThumbnails();
+			}
+		}
+	}
+
+	@Override
+	public void handleLowMemory() {
+		clearUnusedThumbnails();
+		GridDrawables.sStringTextureTable.clear();
+		mBackground.clearCache();
+	}
+
+	// This method can be potentially expensive
+	public void clearUnusedThumbnails() {
+		sDisplayList.clearExcept(sDisplayItems);
+	}
+
+	@Override
+	public void onSurfaceCreated(RenderView view, GL11 gl) {
+		sDisplayList.clear();
+		sHud.clear();
+		sHud.reset();
+		GridDrawables.sStringTextureTable.clear();
+		mDrawables.onSurfaceCreated(view, gl);
+		mBackground.clear();
+	}
+
+	@Override
+	public void onSurfaceChanged(RenderView view, int width, int height) {
+		mCamera.viewportChanged(width, height, mCamera.mItemWidth, mCamera.mItemHeight);
+		view.setFov(mCamera.mFov);
+		setState(mState);
+	}
 
-    @Override
-    public void handleLowMemory() {
-        clearUnusedThumbnails();
-        GridDrawables.sStringTextureTable.clear();
-        mBackground.clearCache();
-    }
+	// Renders the node in a given pass.
+	public void renderOpaque(RenderView view, GL11 gl) {
+		GridCamera camera = mCamera;
+		int selectedSlotIndex = mInputProcessor.getCurrentSelectedSlot();
+		computeVisibleItems();
 
-    // This method can be potentially expensive
-    public void clearUnusedThumbnails() {
-        sDisplayList.clearExcept(sDisplayItems);
-    }
+		gl.glMatrixMode(GL11.GL_MODELVIEW);
+		gl.glLoadIdentity();
+		GLU.gluLookAt(gl, -camera.mEyeX, -camera.mEyeY, -camera.mEyeZ, -camera.mLookAtX, -camera.mLookAtY, -camera.mLookAtZ,
+		        camera.mUpX, camera.mUpY, camera.mUpZ);
+		view.setAlpha(1.0f);
+		if (mSelectedAlpha != 1.0f) {
+			gl.glEnable(GL11.GL_BLEND);
+			gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
+			view.setAlpha(mSelectedAlpha);
+		}
+		if (selectedSlotIndex != Shared.INVALID) {
+			mTargetAlpha = 0.0f;
+		} else {
+			mTargetAlpha = 1.0f;
+		}
+		mDrawManager.prepareDraw(sBufferedVisibleRange, sVisibleRange, selectedSlotIndex, mInputProcessor.getCurrentFocusSlot(),
+		        mInputProcessor.isFocusItemPressed());
+		if (mSelectedAlpha != 0.0f) {
+			mDrawManager.drawThumbnails(view, gl, mState);
+		}
+		if (mSelectedAlpha != 1.0f) {
+			gl.glDisable(GL11.GL_BLEND);
+		}
+		// We draw the selected slotIndex.
+		if (selectedSlotIndex != Shared.INVALID) {
+			mDrawManager.drawFocusItems(view, gl, mZoomValue, mSlideshowMode, mTimeElapsedSinceView);
+			mCurrentFocusItemWidth = mDrawManager.getFocusQuadWidth();
+			mCurrentFocusItemHeight = mDrawManager.getFocusQuadHeight();
+		}
+		view.setAlpha(mSelectedAlpha);
+	}
 
-    @Override
-    public void onSurfaceCreated(RenderView view, GL11 gl) {
-        sDisplayList.clear();
-        sHud.clear();
-        sHud.reset();
-        GridDrawables.sStringTextureTable.clear();
-        mDrawables.onSurfaceCreated(view, gl);
-        mBackground.clear();
-    }
+	public void renderBlended(RenderView view, GL11 gl) {
+		// We draw the placeholder for all visible slots.
+		if (sHud != null && mDrawManager != null) {
+			mDrawManager.drawBlendedComponents(view, gl, mSelectedAlpha, mState, sHud.getMode(), mTimeElapsedSinceStackViewReady,
+			        mTimeElapsedSinceGridViewReady, sBucketList, mMediaFeed.getWaitingForMediaScanner() || mFeedAboutToChange
+			                || mMediaFeed.isLoading());
+		}
+	}
 
-    @Override
-    public void onSurfaceChanged(RenderView view, int width, int height) {
-        mCamera.viewportChanged(width, height, mCamera.mItemWidth, mCamera.mItemHeight);
-        view.setFov(mCamera.mFov);
-        setState(mState);
-    }
+	public synchronized void onLayout(int newAnchorSlotIndex, int currentAnchorSlotIndex, LayoutInterface oldLayout) {
+		if (mPerformingLayoutChange || !sDeltaAnchorPosition.equals(sDeltaAnchorPositionUncommited)) {
+			return;
+		}
 
-    // Renders the node in a given pass.
-    public void renderOpaque(RenderView view, GL11 gl) {
-        GridCamera camera = mCamera;
-        int selectedSlotIndex = mInputProcessor.getCurrentSelectedSlot();
-        computeVisibleItems();
-        
-        gl.glMatrixMode(GL11.GL_MODELVIEW);
-        gl.glLoadIdentity();
-        GLU.gluLookAt(gl, -camera.mEyeX, -camera.mEyeY, -camera.mEyeZ, -camera.mLookAtX, -camera.mLookAtY, -camera.mLookAtZ,
-                camera.mUpX, camera.mUpY, camera.mUpZ);
-        view.setAlpha(1.0f);
-        if (mSelectedAlpha != 1.0f) {
-            gl.glEnable(GL11.GL_BLEND);
-            gl.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
-            view.setAlpha(mSelectedAlpha);
-        }
-        if (selectedSlotIndex != Shared.INVALID) {
-            mTargetAlpha = 0.0f;
-        } else {
-            mTargetAlpha = 1.0f;
-        }
-        mDrawManager.prepareDraw(sBufferedVisibleRange, sVisibleRange, selectedSlotIndex, mInputProcessor.getCurrentFocusSlot(),
-                mInputProcessor.isFocusItemPressed());
-        if (mSelectedAlpha != 0.0f) {
-            mDrawManager.drawThumbnails(view, gl, mState);
-        }
-        if (mSelectedAlpha != 1.0f) {
-            gl.glDisable(GL11.GL_BLEND);
-        }
-        // We draw the selected slotIndex.
-        if (selectedSlotIndex != Shared.INVALID) {
-            mDrawManager.drawFocusItems(view, gl, mZoomValue, mSlideshowMode, mTimeElapsedSinceView);
-            mCurrentFocusItemWidth = mDrawManager.getFocusQuadWidth();
-            mCurrentFocusItemHeight = mDrawManager.getFocusQuadHeight();
-        }
-        view.setAlpha(mSelectedAlpha);
-    }
+		mTimeElapsedSinceTransition = 0.0f;
+		mPerformingLayoutChange = true;
+		LayoutInterface layout = mLayoutInterface;
+		if (oldLayout == null) {
+			oldLayout = sfullScreenLayoutInterface;
+		}
+		GridCamera camera = mCamera;
+		if (currentAnchorSlotIndex == Shared.INVALID) {
+			currentAnchorSlotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
+			if (mCurrentExpandedSlot != Shared.INVALID) {
+				currentAnchorSlotIndex = mCurrentExpandedSlot;
+			}
+			int selectedSlotIndex = mInputProcessor.getCurrentSelectedSlot();
+			if (selectedSlotIndex != Shared.INVALID) {
+				currentAnchorSlotIndex = selectedSlotIndex;
+			}
+		}
+		if (newAnchorSlotIndex == Shared.INVALID) {
+			newAnchorSlotIndex = currentAnchorSlotIndex;
+		}
+		int itemHeight = camera.mItemHeight;
+		int itemWidth = camera.mItemWidth;
+		Pool<Vector3f> pool = sTempVec;
+		Vector3f deltaAnchorPosition = pool.create();
+		Vector3f currentSlotPosition = pool.create();
+		try {
+			deltaAnchorPosition.set(0, 0, 0);
+			if (currentAnchorSlotIndex != Shared.INVALID && newAnchorSlotIndex != Shared.INVALID) {
+				layout.getPositionForSlotIndex(newAnchorSlotIndex, itemWidth, itemHeight, deltaAnchorPosition);
+				oldLayout.getPositionForSlotIndex(currentAnchorSlotIndex, itemWidth, itemHeight, currentSlotPosition);
+				currentSlotPosition.subtract(sDeltaAnchorPosition);
+				deltaAnchorPosition.subtract(currentSlotPosition);
+				deltaAnchorPosition.y = 0;
+				deltaAnchorPosition.z = 0;
+			}
+			sDeltaAnchorPositionUncommited.set(deltaAnchorPosition);
+		} finally {
+			pool.delete(deltaAnchorPosition);
+			pool.delete(currentSlotPosition);
+		}
+		centerCameraForSlot(newAnchorSlotIndex, 1.0f);
+		mCurrentExpandedSlot = Shared.INVALID;
 
-    public void renderBlended(RenderView view, GL11 gl) {
-        // We draw the placeholder for all visible slots.
-        if (sHud != null && mDrawManager != null) {
-            mDrawManager.drawBlendedComponents(view, gl, mSelectedAlpha, mState, sHud.getMode(), mTimeElapsedSinceStackViewReady,
-                    mTimeElapsedSinceGridViewReady, sBucketList, mMediaFeed.getWaitingForMediaScanner() || mFeedAboutToChange
-                            || mMediaFeed.isLoading());
-        }
-    }
+		// Force recompute of visible items and their positions.
+		((GridLayoutInterface) oldLayout).mNumRows = ((GridLayoutInterface) layout).mNumRows;
+		((GridLayoutInterface) oldLayout).mSpacingX = ((GridLayoutInterface) layout).mSpacingX;
+		((GridLayoutInterface) oldLayout).mSpacingY = ((GridLayoutInterface) layout).mSpacingY;
+		forceRecomputeVisibleRange();
+		mPerformingLayoutChange = false;
+	}
 
-    public synchronized void onLayout(int newAnchorSlotIndex, int currentAnchorSlotIndex, LayoutInterface oldLayout) {
-        if (mPerformingLayoutChange || !sDeltaAnchorPosition.equals(sDeltaAnchorPositionUncommited)) {
-            return;
-        }
+	private void forceRecomputeVisibleRange() {
+		sPreviousDataRange.begin = Shared.INVALID;
+		sPreviousDataRange.end = Shared.INVALID;
+		if (mView != null) {
+			mView.requestRender();
+		}
+	}
 
-        mTimeElapsedSinceTransition = 0.0f;
-        mPerformingLayoutChange = true;
-        LayoutInterface layout = mLayoutInterface;
-        if (oldLayout == null) {
-            oldLayout = sfullScreenLayoutInterface;
-        }
-        GridCamera camera = mCamera;
-        if (currentAnchorSlotIndex == Shared.INVALID) {
-            currentAnchorSlotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
-            if (mCurrentExpandedSlot != Shared.INVALID) {
-                currentAnchorSlotIndex = mCurrentExpandedSlot;
-            }
-            int selectedSlotIndex = mInputProcessor.getCurrentSelectedSlot();
-            if (selectedSlotIndex != Shared.INVALID) {
-                currentAnchorSlotIndex = selectedSlotIndex;
-            }
-        }
-        if (newAnchorSlotIndex == Shared.INVALID) {
-            newAnchorSlotIndex = currentAnchorSlotIndex;
-        }
-        int itemHeight = camera.mItemHeight;
-        int itemWidth = camera.mItemWidth;
-        Pool<Vector3f> pool = sTempVec;
-        Vector3f deltaAnchorPosition = pool.create();
-        Vector3f currentSlotPosition = pool.create();
-        try {
-            deltaAnchorPosition.set(0, 0, 0);
-            if (currentAnchorSlotIndex != Shared.INVALID && newAnchorSlotIndex != Shared.INVALID) {
-                layout.getPositionForSlotIndex(newAnchorSlotIndex, itemWidth, itemHeight, deltaAnchorPosition);
-                oldLayout.getPositionForSlotIndex(currentAnchorSlotIndex, itemWidth, itemHeight, currentSlotPosition);
-                currentSlotPosition.subtract(sDeltaAnchorPosition);
-                deltaAnchorPosition.subtract(currentSlotPosition);
-                deltaAnchorPosition.y = 0;
-                deltaAnchorPosition.z = 0;
-            }
-            sDeltaAnchorPositionUncommited.set(deltaAnchorPosition);
-        } finally {
-            pool.delete(deltaAnchorPosition);
-            pool.delete(currentSlotPosition);
-        }
-        centerCameraForSlot(newAnchorSlotIndex, 1.0f);
-        mCurrentExpandedSlot = Shared.INVALID;
-        
-        // Force recompute of visible items and their positions.
-        ((GridLayoutInterface) oldLayout).mNumRows = ((GridLayoutInterface) layout).mNumRows;
-        ((GridLayoutInterface) oldLayout).mSpacingX = ((GridLayoutInterface) layout).mSpacingX;
-        ((GridLayoutInterface) oldLayout).mSpacingY = ((GridLayoutInterface) layout).mSpacingY;
-        forceRecomputeVisibleRange();
-        mPerformingLayoutChange = false;
-    }
+	// called on background thread
+	public synchronized void onFeedChanged(MediaFeed feed, boolean needsLayout) {
+		if (!needsLayout) {
+			mFeedChanged = true;
+			forceRecomputeVisibleRange();
+			if (mState == STATE_GRID_VIEW || mState == STATE_FULL_SCREEN)
+				sHud.setFeed(feed, mState, needsLayout);
+			return;
+		}
 
-    private void forceRecomputeVisibleRange() {
-        sPreviousDataRange.begin = Shared.INVALID;
-        sPreviousDataRange.end = Shared.INVALID;
-        if (mView != null) {
-            mView.requestRender();
-        }
-    }
+		while (mPerformingLayoutChange == true) {
+			Thread.yield();
+		}
+		if (mState == STATE_GRID_VIEW) {
+			if (sHud != null) {
+				MediaSet set = feed.getCurrentSet();
+				if (set != null && !mLocationFilter)
+					sHud.getPathBar().changeLabel(set.mNoCountTitleString);
+			}
+		}
+		DisplayItem[] displayItems = sDisplayItems;
+		int firstBufferedVisibleSlotIndex = sBufferedVisibleRange.begin;
+		int lastBufferedVisibleSlotIndex = sBufferedVisibleRange.end;
+		int currentlyVisibleSlotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
+		if (mCurrentExpandedSlot != Shared.INVALID) {
+			currentlyVisibleSlotIndex = mCurrentExpandedSlot;
+		}
+		MediaItem anchorItem = null;
+		ArrayList<MediaItem> visibleItems = sVisibleItems;
+		visibleItems.clear();
+		visibleItems.ensureCapacity(lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex);
+		if (currentlyVisibleSlotIndex != Shared.INVALID && currentlyVisibleSlotIndex >= firstBufferedVisibleSlotIndex
+		        && currentlyVisibleSlotIndex <= lastBufferedVisibleSlotIndex) {
+			int baseIndex = (currentlyVisibleSlotIndex - firstBufferedVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
+			for (int i = 0; i < MAX_ITEMS_PER_SLOT; ++i) {
+				DisplayItem displayItem = displayItems[baseIndex + i];
+				if (displayItem != null) {
+					if (anchorItem == null) {
+						anchorItem = displayItem.mItemRef;
+					}
+					visibleItems.add(displayItem.mItemRef);
+				}
+			}
+		}
+		// We want to add items from the middle.
+		int numItems = lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex + 1;
+		int midPoint = (lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex) / 2;
+		int length = displayItems.length;
+		for (int i = 0; i < numItems; ++i) {
+			int index = midPoint + Shared.midPointIterator(i);
+			int indexIntoDisplayItem = (index - firstBufferedVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
+			if (indexIntoDisplayItem >= 0 && indexIntoDisplayItem < length) {
+				for (int j = 0; j < MAX_ITEMS_PER_SLOT; ++j) {
+					DisplayItem displayItem = displayItems[indexIntoDisplayItem + j];
+					if (displayItem != null) {
+						MediaItem item = displayItem.mItemRef;
+						if (item != anchorItem) {
+							visibleItems.add(item);
+						}
+					}
+				}
+			}
+		}
+		int newSlotIndex = Shared.INVALID;
+		if (anchorItem != null) {
+			// We try to find the anchor item in the new feed.
+			int numSlots = feed.getNumSlots();
+			for (int i = 0; i < numSlots; ++i) {
+				MediaSet set = feed.getSetForSlot(i);
+				if (set != null && set.containsItem(anchorItem)) {
+					newSlotIndex = i;
+					break;
+				}
+			}
+		}
 
-    // called on background thread
-    public synchronized void onFeedChanged(MediaFeed feed, boolean needsLayout) {
-        if (!needsLayout) {
-            mFeedChanged = true;
-            forceRecomputeVisibleRange();
-            if (mState == STATE_GRID_VIEW || mState == STATE_FULL_SCREEN)
-                sHud.setFeed(feed, mState, needsLayout);
-            return;
-        }
+		if (anchorItem != null && newSlotIndex == Shared.INVALID) {
+			int numSlots = feed.getNumSlots();
+			MediaSet parentSet = anchorItem.mParentMediaSet;
+			for (int i = 0; i < numSlots; ++i) {
+				MediaSet set = feed.getSetForSlot(i);
+				if (set != null && set.mId == parentSet.mId) {
+					newSlotIndex = i;
+					break;
+				}
+			}
+		}
 
-        while (mPerformingLayoutChange == true) {
-            Thread.yield();
-        }
-        if (mState == STATE_GRID_VIEW) {
-            if (sHud != null) {
-                MediaSet set = feed.getCurrentSet();
-                if (set != null && !mLocationFilter)
-                    sHud.getPathBar().changeLabel(set.mNoCountTitleString);
-            }
-        }
-        DisplayItem[] displayItems = sDisplayItems;
-        int firstBufferedVisibleSlotIndex = sBufferedVisibleRange.begin;
-        int lastBufferedVisibleSlotIndex = sBufferedVisibleRange.end;
-        int currentlyVisibleSlotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
-        if (mCurrentExpandedSlot != Shared.INVALID) {
-            currentlyVisibleSlotIndex = mCurrentExpandedSlot;
-        }
-        MediaItem anchorItem = null;
-        ArrayList<MediaItem> visibleItems = sVisibleItems;
-        visibleItems.clear();
-        visibleItems.ensureCapacity(lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex);
-        if (currentlyVisibleSlotIndex != Shared.INVALID && currentlyVisibleSlotIndex >= firstBufferedVisibleSlotIndex
-                && currentlyVisibleSlotIndex <= lastBufferedVisibleSlotIndex) {
-            int baseIndex = (currentlyVisibleSlotIndex - firstBufferedVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
-            for (int i = 0; i < MAX_ITEMS_PER_SLOT; ++i) {
-                DisplayItem displayItem = displayItems[baseIndex + i];
-                if (displayItem != null) {
-                    if (anchorItem == null) {
-                        anchorItem = displayItem.mItemRef;
-                    }
-                    visibleItems.add(displayItem.mItemRef);
-                }
-            }
-        }
-        // We want to add items from the middle.
-        int numItems = lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex + 1;
-        int midPoint = (lastBufferedVisibleSlotIndex - firstBufferedVisibleSlotIndex) / 2;
-        int length = displayItems.length;
-        for (int i = 0; i < numItems; ++i) {
-            int index = midPoint + Shared.midPointIterator(i);
-            int indexIntoDisplayItem = (index - firstBufferedVisibleSlotIndex) * MAX_ITEMS_PER_SLOT;
-            if (indexIntoDisplayItem >= 0 && indexIntoDisplayItem < length) {
-                for (int j = 0; j < MAX_ITEMS_PER_SLOT; ++j) {
-                    DisplayItem displayItem = displayItems[indexIntoDisplayItem + j];
-                    if (displayItem != null) {
-                        MediaItem item = displayItem.mItemRef;
-                        if (item != anchorItem) {
-                            visibleItems.add(item);
-                        }
-                    }
-                }
-            }
-        }
-        int newSlotIndex = Shared.INVALID;
-        if (anchorItem != null) {
-            // We try to find the anchor item in the new feed.
-            int numSlots = feed.getNumSlots();
-            for (int i = 0; i < numSlots; ++i) {
-                MediaSet set = feed.getSetForSlot(i);
-                if (set != null && set.containsItem(anchorItem)) {
-                    newSlotIndex = i;
-                    break;
-                }
-            }
-        }
+		// We must create a new display store now since the data has changed.
+		if (newSlotIndex != Shared.INVALID) {
+			if (mState == STATE_MEDIA_SETS) {
+				sDisplayList.clearExcept(displayItems);
+			}
+			onLayout(newSlotIndex, currentlyVisibleSlotIndex, null);
+		} else {
+			forceRecomputeVisibleRange();
+		}
+		mCurrentExpandedSlot = Shared.INVALID;
+		mFeedAboutToChange = false;
+		mFeedChanged = true;
+		if (feed != null) {
+			if (mState == STATE_GRID_VIEW || mState == STATE_FULL_SCREEN)
+				sHud.setFeed(feed, mState, needsLayout);
+		}
+		if (mView != null) {
+			mView.requestRender();
+		}
+	}
 
-        if (anchorItem != null && newSlotIndex == Shared.INVALID) {
-            int numSlots = feed.getNumSlots();
-            MediaSet parentSet = anchorItem.mParentMediaSet;
-            for (int i = 0; i < numSlots; ++i) {
-                MediaSet set = feed.getSetForSlot(i);
-                if (set != null && set.mId == parentSet.mId) {
-                    newSlotIndex = i;
-                    break;
-                }
-            }
-        }
-        
-        // We must create a new display store now since the data has changed.
-        if (newSlotIndex != Shared.INVALID) {
-            if (mState == STATE_MEDIA_SETS) {
-                sDisplayList.clearExcept(displayItems);
-            }
-            onLayout(newSlotIndex, currentlyVisibleSlotIndex, null);
-        } else {
-            forceRecomputeVisibleRange();
-        }
-        mCurrentExpandedSlot = Shared.INVALID;
-        mFeedAboutToChange = false;
-        mFeedChanged = true;
-        if (feed != null) {
-            if (mState == STATE_GRID_VIEW || mState == STATE_FULL_SCREEN)
-                sHud.setFeed(feed, mState, needsLayout);
-        }
-        if (mView != null) {
-            mView.requestRender();
-        }
-    }
-    
-    public DisplayItem getRepresentativeDisplayItem() {
-        int slotIndex = Shared.INVALID;
-        if (mInputProcessor != null) {
-            slotIndex = mInputProcessor.getCurrentFocusSlot();
-        }
-        if (slotIndex == Shared.INVALID) {
-            slotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
-        }
-        int index = (slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT;
-        if (index >= 0 && index < MAX_ITEMS_DRAWABLE) {
-            return sDisplayItems[index];
-        } else {
-            return null;
-        }
-    }
+	public DisplayItem getRepresentativeDisplayItem() {
+		int slotIndex = Shared.INVALID;
+		if (mInputProcessor != null) {
+			slotIndex = mInputProcessor.getCurrentFocusSlot();
+		}
+		if (slotIndex == Shared.INVALID) {
+			slotIndex = getAnchorSlotIndex(ANCHOR_CENTER);
+		}
+		int index = (slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT;
+		if (index >= 0 && index < MAX_ITEMS_DRAWABLE) {
+			return sDisplayItems[index];
+		} else {
+			return null;
+		}
+	}
 
-    public DisplayItem getAnchorDisplayItem(int type) {
-        int slotIndex = getAnchorSlotIndex(type);
-        return sDisplayItems[(slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT];
-    }
+	public DisplayItem getAnchorDisplayItem(int type) {
+		int slotIndex = getAnchorSlotIndex(type);
+		return sDisplayItems[(slotIndex - sBufferedVisibleRange.begin) * MAX_ITEMS_PER_SLOT];
+	}
 
-    public float getScrollPosition() {
-        return (mCamera.mLookAtX * mCamera.mScale + sDeltaAnchorPosition.x); // in
-        // pixels
-    }
+	public float getScrollPosition() {
+		return (mCamera.mLookAtX * mCamera.mScale + sDeltaAnchorPosition.x); // in
+		// pixels
+	}
 
-    public DisplayItem getDisplayItemForScrollPosition(float posX) {
-        Pool<Vector3f> pool = sTempVecAlt;
-        MediaFeed feed = mMediaFeed;
-        int itemWidth = mCamera.mItemWidth;
-        int itemHeight = mCamera.mItemHeight;
-        GridLayoutInterface gridInterface = (GridLayoutInterface) mLayoutInterface;
-        float absolutePosX = posX;
-        int left = (int) ((absolutePosX / itemWidth) * gridInterface.mNumRows);
-        int right = feed == null ? 0 : (int) (feed.getNumSlots());
-        int retSlot = left;
-        Vector3f position = pool.create();
-        try {
-            for (int i = left; i < right; ++i) {
-                gridInterface.getPositionForSlotIndex(i, itemWidth, itemHeight, position);
-                retSlot = i;
-                if (position.x >= absolutePosX) {
-                    break;
-                }
-            }
-        } finally {
-            pool.delete(position);
-        }
-        if (mFeedAboutToChange) {
-            return null;
-        }
-        right = feed == null ? 0 : feed.getNumSlots();
-        if (right == 0) {
-            return null;
-        }
+	public DisplayItem getDisplayItemForScrollPosition(float posX) {
+		Pool<Vector3f> pool = sTempVecAlt;
+		MediaFeed feed = mMediaFeed;
+		int itemWidth = mCamera.mItemWidth;
+		int itemHeight = mCamera.mItemHeight;
+		GridLayoutInterface gridInterface = (GridLayoutInterface) mLayoutInterface;
+		float absolutePosX = posX;
+		int left = (int) ((absolutePosX / itemWidth) * gridInterface.mNumRows);
+		int right = feed == null ? 0 : (int) (feed.getNumSlots());
+		int retSlot = left;
+		Vector3f position = pool.create();
+		try {
+			for (int i = left; i < right; ++i) {
+				gridInterface.getPositionForSlotIndex(i, itemWidth, itemHeight, position);
+				retSlot = i;
+				if (position.x >= absolutePosX) {
+					break;
+				}
+			}
+		} finally {
+			pool.delete(position);
+		}
+		if (mFeedAboutToChange) {
+			return null;
+		}
+		right = feed == null ? 0 : feed.getNumSlots();
+		if (right == 0) {
+			return null;
+		}
 
-        if (retSlot >= right)
-            retSlot = right - 1;
-        MediaSet set = feed.getSetForSlot(retSlot);
-        if (set != null) {
-            ArrayList<MediaItem> items = set.getItems();
-            if (items != null && set.getNumItems() > 0) {
-                return (sDisplayList.get(items.get(0)));
-            }
-        }
-        return null;
-    }
+		if (retSlot >= right)
+			retSlot = right - 1;
+		MediaSet set = feed.getSetForSlot(retSlot);
+		if (set != null) {
+			ArrayList<MediaItem> items = set.getItems();
+			if (items != null && set.getNumItems() > 0) {
+				return (sDisplayList.get(items.get(0)));
+			}
+		}
+		return null;
+	}
 
-    // Returns the top left-most item.
-    public int getAnchorSlotIndex(int anchorType) {
-        int retVal = 0;
-        switch (anchorType) {
-        case ANCHOR_LEFT:
-            retVal = sVisibleRange.begin;
-            break;
-        case ANCHOR_RIGHT:
-            retVal = sVisibleRange.end;
-            break;
-        case ANCHOR_CENTER:
-            retVal = (sVisibleRange.begin + sVisibleRange.end) / 2;
-            break;
-        }
-        return retVal;
-    }
+	// Returns the top left-most item.
+	public int getAnchorSlotIndex(int anchorType) {
+		int retVal = 0;
+		switch (anchorType) {
+		case ANCHOR_LEFT:
+			retVal = sVisibleRange.begin;
+			break;
+		case ANCHOR_RIGHT:
+			retVal = sVisibleRange.end;
+			break;
+		case ANCHOR_CENTER:
+			retVal = (sVisibleRange.begin + sVisibleRange.end) / 2;
+			break;
+		}
+		return retVal;
+	}
 
-    DisplayItem getDisplayItemForSlotId(int slotId) {
-        int index = slotId - sBufferedVisibleRange.begin;
-        if (index >= 0 && slotId <= sBufferedVisibleRange.end) {
-            return sDisplayItems[index * MAX_ITEMS_PER_SLOT];
-        }
-        return null;
-    }
+	DisplayItem getDisplayItemForSlotId(int slotId) {
+		int index = slotId - sBufferedVisibleRange.begin;
+		if (index >= 0 && slotId <= sBufferedVisibleRange.end) {
+			return sDisplayItems[index * MAX_ITEMS_PER_SLOT];
+		}
+		return null;
+	}
 
-    boolean changeFocusToNextSlot(float convergence) {
-        int currentSelectedSlot = mInputProcessor.getCurrentSelectedSlot();
-        boolean retVal = changeFocusToSlot(currentSelectedSlot + 1, convergence);
-        if (mInputProcessor.getCurrentSelectedSlot() == currentSelectedSlot) {
-            endSlideshow();
-            sHud.setAlpha(1.0f);
-        }
-        return retVal;
-    }
+	boolean changeFocusToNextSlot(float convergence) {
+		int currentSelectedSlot = mInputProcessor.getCurrentSelectedSlot();
+		boolean retVal = changeFocusToSlot(currentSelectedSlot + 1, convergence);
+		if (mInputProcessor.getCurrentSelectedSlot() == currentSelectedSlot) {
+			endSlideshow();
+			sHud.setAlpha(1.0f);
+		}
+		return retVal;
+	}
 
-    boolean changeFocusToSlot(int slotId, float convergence) {
-        mZoomValue = 1.0f;
-        int index = slotId - sBufferedVisibleRange.begin;
-        if (index >= 0 && slotId <= sBufferedVisibleRange.end) {
-            DisplayItem displayItem = sDisplayItems[index * MAX_ITEMS_PER_SLOT];
-            if (displayItem != null) {
-                MediaItem item = displayItem.mItemRef;
-                sHud.fullscreenSelectionChanged(item, slotId + 1, sCompleteRange.end + 1);
-                if (slotId != Shared.INVALID && slotId <= sCompleteRange.end) {
-                    mInputProcessor.setCurrentFocusSlot(slotId);
-                    centerCameraForSlot(slotId, convergence);
-                    return true;
-                } else {
-                    centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), convergence);
-                    return false;
-                }
-            }
-        }
-        return false;
-    }
+	boolean changeFocusToSlot(int slotId, float convergence) {
+		mZoomValue = 1.0f;
+		int index = slotId - sBufferedVisibleRange.begin;
+		if (index >= 0 && slotId <= sBufferedVisibleRange.end) {
+			DisplayItem displayItem = sDisplayItems[index * MAX_ITEMS_PER_SLOT];
+			if (displayItem != null) {
+				MediaItem item = displayItem.mItemRef;
+				sHud.fullscreenSelectionChanged(item, slotId + 1, sCompleteRange.end + 1);
+				if (slotId != Shared.INVALID && slotId <= sCompleteRange.end) {
+					mInputProcessor.setCurrentFocusSlot(slotId);
+					centerCameraForSlot(slotId, convergence);
+					return true;
+				} else {
+					centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), convergence);
+					return false;
+				}
+			}
+		}
+		return false;
+	}
 
-    boolean changeFocusToPreviousSlot(float convergence) {
-        return changeFocusToSlot(mInputProcessor.getCurrentSelectedSlot() - 1, convergence);
-    }
+	boolean changeFocusToPreviousSlot(float convergence) {
+		return changeFocusToSlot(mInputProcessor.getCurrentSelectedSlot() - 1, convergence);
+	}
 
-    public ArrayList<MediaBucket> getSelectedBuckets() {
-        return sBucketList.get();
-    }
+	public ArrayList<MediaBucket> getSelectedBuckets() {
+		return sBucketList.get();
+	}
 
-    public void selectAll() {
-        if (mState != STATE_FULL_SCREEN) {
-            int numSlots = sCompleteRange.end + 1;
-            for (int i = 0; i < numSlots; ++i) {
-                addSlotToSelectedItems(i, false, false);
-            }
-            updateCountOfSelectedItems();
-        } else {
-            addSlotToSelectedItems(mInputProcessor.getCurrentFocusSlot(), false, true);
-        }
-    }
+	public void selectAll() {
+		if (mState != STATE_FULL_SCREEN) {
+			int numSlots = sCompleteRange.end + 1;
+			for (int i = 0; i < numSlots; ++i) {
+				addSlotToSelectedItems(i, false, false);
+			}
+			updateCountOfSelectedItems();
+		} else {
+			addSlotToSelectedItems(mInputProcessor.getCurrentFocusSlot(), false, true);
+		}
+	}
 
-    public void deselectOrCancelSelectMode() {
-        if (sBucketList.size() == 0) {
-            sHud.cancelSelection();
-        } else {
-            sBucketList.clear();
-            updateCountOfSelectedItems();
-        }
-    }
+	public void deselectOrCancelSelectMode() {
+		if (sBucketList.size() == 0) {
+			sHud.cancelSelection();
+		} else {
+			sBucketList.clear();
+			updateCountOfSelectedItems();
+		}
+	}
 
-    public void deselectAll() {
-        sHud.cancelSelection();
-        sBucketList.clear();
-        updateCountOfSelectedItems();
-    }
+	public void deselectAll() {
+		sHud.cancelSelection();
+		sBucketList.clear();
+		updateCountOfSelectedItems();
+	}
 
-    public void deleteSelection() {
-        // Delete the selection and exit selection mode.
-        mMediaFeed.performOperation(MediaFeed.OPERATION_DELETE, getSelectedBuckets(), null);
-        deselectAll();
+	public void deleteSelection() {
+		// Delete the selection and exit selection mode.
+		mMediaFeed.performOperation(MediaFeed.OPERATION_DELETE, getSelectedBuckets(), null);
+		deselectAll();
 
-        // If the current set is now empty, return to the parent set.
-        if (sCompleteRange.isEmpty()) {
-            goBack(); // TODO(venkat): This does not work most of the time, can you take a look?
-        }
-    }
+		// If the current set is now empty, return to the parent set.
+		if (sCompleteRange.isEmpty()) {
+			goBack(); // TODO(venkat): This does not work most of the time, can
+					  // you take a look?
+		}
+	}
 
-    void addSlotToSelectedItems(int slotId, boolean removeIfAlreadyAdded, boolean updateCount) {
-        if (mFeedAboutToChange == false) {
-            MediaFeed feed = mMediaFeed;
-            sBucketList.add(slotId, feed, removeIfAlreadyAdded);
-            if (updateCount) {
-                updateCountOfSelectedItems();
-                if (sBucketList.size() == 0)
-                    deselectAll();
-            }
-        }
-    }
+	void addSlotToSelectedItems(int slotId, boolean removeIfAlreadyAdded, boolean updateCount) {
+		if (mFeedAboutToChange == false) {
+			MediaFeed feed = mMediaFeed;
+			sBucketList.add(slotId, feed, removeIfAlreadyAdded);
+			if (updateCount) {
+				updateCountOfSelectedItems();
+				if (sBucketList.size() == 0)
+					deselectAll();
+			}
+		}
+		sHud.computeBottomMenu();
+	}
 
-    private void updateCountOfSelectedItems() {
-        sHud.updateNumItemsSelected(sBucketList.size());
-    }
+	private void updateCountOfSelectedItems() {
+		sHud.updateNumItemsSelected(sBucketList.size());
+	}
 
-    public int getMetadataSlotIndexForScreenPosition(int posX, int posY) {
-        return getSlotForScreenPosition(posX, posY, mCamera.mItemWidth + (int) (100 * Gallery.PIXEL_DENSITY), mCamera.mItemHeight
-                + (int) (100 * Gallery.PIXEL_DENSITY));
-    }
+	public int getMetadataSlotIndexForScreenPosition(int posX, int posY) {
+		return getSlotForScreenPosition(posX, posY, mCamera.mItemWidth + (int) (100 * Gallery.PIXEL_DENSITY), mCamera.mItemHeight
+		        + (int) (100 * Gallery.PIXEL_DENSITY));
+	}
 
-    public int getSlotIndexForScreenPosition(int posX, int posY) {
-        return getSlotForScreenPosition(posX, posY, mCamera.mItemWidth, mCamera.mItemHeight);
-    }
+	public int getSlotIndexForScreenPosition(int posX, int posY) {
+		return getSlotForScreenPosition(posX, posY, mCamera.mItemWidth, mCamera.mItemHeight);
+	}
 
-    private int getSlotForScreenPosition(int posX, int posY, int itemWidth, int itemHeight) {
-        Pool<Vector3f> pool = sTempVec;
-        int retVal = 0;
-        Vector3f worldPos = pool.create();
-        try {
-            GridCamera camera = mCamera;
-            camera.convertToCameraSpace(posX, posY, 0, worldPos);
-            // slots are expressed in pixels as well
-            worldPos.x *= camera.mScale;
-            worldPos.y *= camera.mScale;
-            // we ignore z
-            retVal = hitTest(worldPos, itemWidth, itemHeight);
-        } finally {
-            pool.delete(worldPos);
-        }
-        return retVal;
-    }
+	private int getSlotForScreenPosition(int posX, int posY, int itemWidth, int itemHeight) {
+		Pool<Vector3f> pool = sTempVec;
+		int retVal = 0;
+		Vector3f worldPos = pool.create();
+		try {
+			GridCamera camera = mCamera;
+			camera.convertToCameraSpace(posX, posY, 0, worldPos);
+			// slots are expressed in pixels as well
+			worldPos.x *= camera.mScale;
+			worldPos.y *= camera.mScale;
+			// we ignore z
+			retVal = hitTest(worldPos, itemWidth, itemHeight);
+		} finally {
+			pool.delete(worldPos);
+		}
+		return retVal;
+	}
 
-    public boolean tapGesture(int slotIndex, boolean metadata) {
-        MediaFeed feed = mMediaFeed;
-        if (!feed.isClustered()) {
-            // It is not clustering.
-            if (!feed.hasExpandedMediaSet()) {
-                if (feed.canExpandSet(slotIndex)) {
-                    mCurrentExpandedSlot = slotIndex;
-                    feed.expandMediaSet(slotIndex);
-                    setState(STATE_GRID_VIEW);
-                }
-                return false;
-            } else {
-                return true;
-            }
-        } else {
-            // Select a cluster, and recompute a new cluster within this cluster.
-            mCurrentExpandedSlot = slotIndex;
-            goBack();
-            if (metadata) {
-                DisplaySlot slot = sDisplaySlots[slotIndex - sBufferedVisibleRange.begin];
-                if (slot.hasValidLocation()) {
-                    MediaSet set = slot.getMediaSet();
-                    if (set.mReverseGeocodedLocation != null) {
-                        enableLocationFiltering(set.mReverseGeocodedLocation);
-                    }
-                    feed.setFilter(new LocationMediaFilter(set.mMinLatLatitude, set.mMinLonLongitude, set.mMaxLatLatitude, set.mMaxLonLongitude));
-                }
-            }
-            return false;
-        }
-    }
+	public boolean tapGesture(int slotIndex, boolean metadata) {
+		MediaFeed feed = mMediaFeed;
+		if (!feed.isClustered()) {
+			// It is not clustering.
+			if (!feed.hasExpandedMediaSet()) {
+				if (feed.canExpandSet(slotIndex)) {
+					mCurrentExpandedSlot = slotIndex;
+					feed.expandMediaSet(slotIndex);
+					setState(STATE_GRID_VIEW);
+				}
+				return false;
+			} else {
+				return true;
+			}
+		} else {
+			// Select a cluster, and recompute a new cluster within this
+			// cluster.
+			mCurrentExpandedSlot = slotIndex;
+			goBack();
+			if (metadata) {
+				DisplaySlot slot = sDisplaySlots[slotIndex - sBufferedVisibleRange.begin];
+				if (slot.hasValidLocation()) {
+					MediaSet set = slot.getMediaSet();
+					if (set.mReverseGeocodedLocation != null) {
+						enableLocationFiltering(set.mReverseGeocodedLocation);
+					}
+					feed.setFilter(new LocationMediaFilter(set.mMinLatLatitude, set.mMinLonLongitude, set.mMaxLatLatitude,
+					        set.mMaxLonLongitude));
+				}
+			}
+			return false;
+		}
+	}
 
-    public void onTimeChanged(TimeBar timebar) {
-        if (mFeedAboutToChange) {
-            return;
-        }
-        // TODO lot of optimization possible here
-        MediaItem item = timebar.getItem();
-        MediaFeed feed = mMediaFeed;
-        int numSlots = feed.getNumSlots();
-        for (int i = 0; i < numSlots; ++i) {
-            MediaSet set = feed.getSetForSlot(i);
-            if (set == null) {
-                return;
-            }
-            ArrayList<MediaItem> items = set.getItems();
-            if (items == null || set.getNumItems() == 0) {
-                return;
-            }
-            if (items.contains(item)) {
-                centerCameraForSlot(i, 1.0f);
-                break;
-            }
-        }
-    }
+	public void onTimeChanged(TimeBar timebar) {
+		if (mFeedAboutToChange) {
+			return;
+		}
+		// TODO lot of optimization possible here
+		MediaItem item = timebar.getItem();
+		MediaFeed feed = mMediaFeed;
+		int numSlots = feed.getNumSlots();
+		for (int i = 0; i < numSlots; ++i) {
+			MediaSet set = feed.getSetForSlot(i);
+			if (set == null) {
+				return;
+			}
+			ArrayList<MediaItem> items = set.getItems();
+			if (items == null || set.getNumItems() == 0) {
+				return;
+			}
+			if (items.contains(item)) {
+				centerCameraForSlot(i, 1.0f);
+				break;
+			}
+		}
+	}
 
-    public void onFeedAboutToChange(MediaFeed feed) {
-        mFeedAboutToChange = true;
-        mTimeElapsedSinceTransition = 0;
-    }
+	public void onFeedAboutToChange(MediaFeed feed) {
+		mFeedAboutToChange = true;
+		mTimeElapsedSinceTransition = 0;
+	}
 
-    public void startSlideshow() {
-        endSlideshow();
-        mSlideshowMode = true;
-        mZoomValue = 1.0f;
-        centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
-        mTimeElapsedSinceView = SLIDESHOW_TRANSITION_TIME - 1.0f;
-        sHud.setAlpha(0);
-        PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow");
-        mWakeLock.acquire();
-    }
+	public void startSlideshow() {
+		endSlideshow();
+		mSlideshowMode = true;
+		mZoomValue = 1.0f;
+		centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
+		mTimeElapsedSinceView = SLIDESHOW_TRANSITION_TIME - 1.0f;
+		sHud.setAlpha(0);
+		PowerManager pm = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+		mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK, "GridView.Slideshow");
+		mWakeLock.acquire();
+	}
 
-    public void enterSelectionMode() {
-        mSlideshowMode = false;
-        sHud.enterSelectionMode();
-        int currentSlot = mInputProcessor.getCurrentSelectedSlot();
-        if (currentSlot == Shared.INVALID) {
-            currentSlot = mInputProcessor.getCurrentFocusSlot();
-        }
-        addSlotToSelectedItems(currentSlot, false, true);
-    }
+	public void enterSelectionMode() {
+		mSlideshowMode = false;
+		sHud.enterSelectionMode();
+		int currentSlot = mInputProcessor.getCurrentSelectedSlot();
+		if (currentSlot == Shared.INVALID) {
+			currentSlot = mInputProcessor.getCurrentFocusSlot();
+		}
+		addSlotToSelectedItems(currentSlot, false, true);
+	}
 
-    private float getFillScreenZoomValue() {
-        return GridCameraManager.getFillScreenZoomValue(mCamera, sTempVec, mCurrentFocusItemWidth, mCurrentFocusItemHeight);
-    }
+	private float getFillScreenZoomValue() {
+		return GridCameraManager.getFillScreenZoomValue(mCamera, sTempVec, mCurrentFocusItemWidth, mCurrentFocusItemHeight);
+	}
 
-    public void zoomInToSelectedItem() {
-        mSlideshowMode = false;
-        float potentialZoomValue = getFillScreenZoomValue();
-        if (mZoomValue < potentialZoomValue) {
-            mZoomValue = potentialZoomValue;
-        } else {
-            mZoomValue *= 3.0f;
-        }
-        if (mZoomValue > 6.0f) {
-            mZoomValue = 6.0f;
-        }
-        sHud.setAlpha(1.0f);
-        centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
-    }
+	public void zoomInToSelectedItem() {
+		mSlideshowMode = false;
+		float potentialZoomValue = getFillScreenZoomValue();
+		if (mZoomValue < potentialZoomValue) {
+			mZoomValue = potentialZoomValue;
+		} else {
+			mZoomValue *= 3.0f;
+		}
+		if (mZoomValue > 6.0f) {
+			mZoomValue = 6.0f;
+		}
+		sHud.setAlpha(1.0f);
+		centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
+	}
 
-    public void zoomOutFromSelectedItem() {
-        mSlideshowMode = false;
-        if (mZoomValue == getFillScreenZoomValue()) {
-            mZoomValue = 1.0f;
-        } else {
-            mZoomValue /= 3.0f;
-        }
-        if (mZoomValue < 1.0f) {
-            mZoomValue = 1.0f;
-        }
-        sHud.setAlpha(1.0f);
-        centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
-    }
+	public void zoomOutFromSelectedItem() {
+		mSlideshowMode = false;
+		if (mZoomValue == getFillScreenZoomValue()) {
+			mZoomValue = 1.0f;
+		} else {
+			mZoomValue /= 3.0f;
+		}
+		if (mZoomValue < 1.0f) {
+			mZoomValue = 1.0f;
+		}
+		sHud.setAlpha(1.0f);
+		centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
+	}
 
-    public void rotateSelectedItems(float f) {
-        MediaBucketList bucketList = sBucketList;
-        ArrayList<MediaBucket> mediaBuckets = bucketList.get();
-        DisplayList displayList = sDisplayList;
-        int numBuckets = mediaBuckets.size();
-        for (int i = 0; i < numBuckets; ++i) {
-            MediaBucket bucket = mediaBuckets.get(i);
-            ArrayList<MediaItem> mediaItems = bucket.mediaItems;
-            if (mediaItems != null) {
-                int numMediaItems = mediaItems.size();
-                for (int j = 0; j < numMediaItems; ++j) {
-                    MediaItem item = mediaItems.get(j);
-                    DisplayItem displayItem = displayList.get(item);
-                    displayItem.rotateImageBy(f);
-                    displayList.addToAnimatables(displayItem);
-                }
-            }
-        }
-        if (mState == STATE_FULL_SCREEN) {
-            centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
-        }
-        mMediaFeed.performOperation(MediaFeed.OPERATION_ROTATE, mediaBuckets, new Float(f));
-        // we recreate these displayitems from the cache
-    }
+	public void rotateSelectedItems(float f) {
+		MediaBucketList bucketList = sBucketList;
+		ArrayList<MediaBucket> mediaBuckets = bucketList.get();
+		DisplayList displayList = sDisplayList;
+		int numBuckets = mediaBuckets.size();
+		for (int i = 0; i < numBuckets; ++i) {
+			MediaBucket bucket = mediaBuckets.get(i);
+			ArrayList<MediaItem> mediaItems = bucket.mediaItems;
+			if (mediaItems != null) {
+				int numMediaItems = mediaItems.size();
+				for (int j = 0; j < numMediaItems; ++j) {
+					MediaItem item = mediaItems.get(j);
+					DisplayItem displayItem = displayList.get(item);
+					displayItem.rotateImageBy(f);
+					displayList.addToAnimatables(displayItem);
+				}
+			}
+		}
+		if (mState == STATE_FULL_SCREEN) {
+			centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
+		}
+		mMediaFeed.performOperation(MediaFeed.OPERATION_ROTATE, mediaBuckets, new Float(f));
+		// we recreate these displayitems from the cache
+	}
 
-    public void cropSelectedItem() {
+	public void cropSelectedItem() {
 
-    }
+	}
 
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        return mInputProcessor.onTouchEvent(event);
-    }
+	@Override
+	public boolean onTouchEvent(MotionEvent event) {
+		return mInputProcessor.onTouchEvent(event);
+	}
 
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (mInputProcessor != null)
-            return mInputProcessor.onKeyDown(keyCode, event, mState);
-        return false;
-    }
+	@Override
+	public boolean onKeyDown(int keyCode, KeyEvent event) {
+		if (mInputProcessor != null)
+			return mInputProcessor.onKeyDown(keyCode, event, mState);
+		return false;
+	}
 
-    public boolean inSlideShowMode() {
-        return mSlideshowMode;
-    }
+	public boolean inSlideShowMode() {
+		return mSlideshowMode;
+	}
 
-    public boolean noDeleteMode() {
-        return mNoDeleteMode || (mMediaFeed != null && mMediaFeed.isSingleImageMode());
-    }
+	public boolean noDeleteMode() {
+		return mNoDeleteMode || (mMediaFeed != null && mMediaFeed.isSingleImageMode());
+	}
 
-    public float getZoomValue() {
-        return mZoomValue;
-    }
+	public float getZoomValue() {
+		return mZoomValue;
+	}
 
-    public boolean feedAboutToChange() {
-        return mFeedAboutToChange;
-    }
+	public boolean feedAboutToChange() {
+		return mFeedAboutToChange;
+	}
 
-    public boolean isInAlbumMode() {
-        return mInAlbum;
-    }
+	public boolean isInAlbumMode() {
+		return mInAlbum;
+	}
 
-    public Vector3f getDeltaAnchorPosition() {
-        return sDeltaAnchorPosition;
-    }
+	public Vector3f getDeltaAnchorPosition() {
+		return sDeltaAnchorPosition;
+	}
 
-    public int getExpandedSlot() {
-        return mCurrentExpandedSlot;
-    }
+	public int getExpandedSlot() {
+		return mCurrentExpandedSlot;
+	}
 
-    public GridLayoutInterface getLayoutInterface() {
-        return (GridLayoutInterface) mLayoutInterface;
-    }
+	public GridLayoutInterface getLayoutInterface() {
+		return (GridLayoutInterface) mLayoutInterface;
+	}
 
-    public void setZoomValue(float f) {
-        mZoomValue = f;
-        centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
-    }
+	public void setZoomValue(float f) {
+		mZoomValue = f;
+		centerCameraForSlot(mInputProcessor.getCurrentSelectedSlot(), 1.0f);
+	}
 
-    public void setPickIntent(boolean b) {
-        mPickIntent = b;
-        sHud.getPathBar().popLabel();
-        sHud.getPathBar().pushLabel(R.drawable.icon_location_small, mContext.getResources().getString(R.string.pick),
-                new Runnable() {
-                    public void run() {
-                        if (sHud.getAlpha() == 1.0f) {
-                            if (!mFeedAboutToChange) {
-                                setState(STATE_MEDIA_SETS);
-                            }
-                        } else {
-                            sHud.setAlpha(1.0f);
-                        }
-                    }
-                });
-    }
+	public void setPickIntent(boolean b) {
+		mPickIntent = b;
+		sHud.getPathBar().popLabel();
+		sHud.getPathBar().pushLabel(R.drawable.icon_location_small, mContext.getResources().getString(R.string.pick),
+		        new Runnable() {
+			        public void run() {
+				        if (sHud.getAlpha() == 1.0f) {
+					        if (!mFeedAboutToChange) {
+						        setState(STATE_MEDIA_SETS);
+					        }
+				        } else {
+					        sHud.setAlpha(1.0f);
+				        }
+			        }
+		        });
+	}
 
-    public boolean getPickIntent() {
-        return mPickIntent;
-    }
+	public boolean getPickIntent() {
+		return mPickIntent;
+	}
 
-    public void setViewIntent(boolean b, final String setName) {
-        mViewIntent = b;
-        if (b) {
-            mMediaFeed.expandMediaSet(0);
-            setState(STATE_GRID_VIEW);
-            // We need to make sure we haven't pushed the same label twice
-            if (sHud.getPathBar().getNumLevels() == 1) {
-                sHud.getPathBar().pushLabel(R.drawable.icon_folder_small, setName, new Runnable() {
-                    public void run() {
-                        if (mFeedAboutToChange) {
-                            return;
-                        }
-                        if (sHud.getAlpha() == 1.0f) {
-                        disableLocationFiltering();
-                        if (mInputProcessor != null)
-                            mInputProcessor.clearSelection();
-                        setState(STATE_GRID_VIEW);
-                        } else {
-                            sHud.setAlpha(1.0f);
-                        }
-                    }
-                });
-            }
-        }
-    }
+	public void setViewIntent(boolean b, final String setName) {
+		mViewIntent = b;
+		if (b) {
+			mMediaFeed.expandMediaSet(0);
+			setState(STATE_GRID_VIEW);
+			// We need to make sure we haven't pushed the same label twice
+			if (sHud.getPathBar().getNumLevels() == 1) {
+				sHud.getPathBar().pushLabel(R.drawable.icon_folder_small, setName, new Runnable() {
+					public void run() {
+						if (mFeedAboutToChange) {
+							return;
+						}
+						if (sHud.getAlpha() == 1.0f) {
+							disableLocationFiltering();
+							if (mInputProcessor != null)
+								mInputProcessor.clearSelection();
+							setState(STATE_GRID_VIEW);
+						} else {
+							sHud.setAlpha(1.0f);
+						}
+					}
+				});
+			}
+		}
+	}
 
-    public boolean getViewIntent() {
-        return mViewIntent;
-    }
+	public boolean getViewIntent() {
+		return mViewIntent;
+	}
 
-    public void setSingleImage(boolean noDeleteMode) {
-        mNoDeleteMode = noDeleteMode;
-        mInputProcessor.setCurrentSelectedSlot(0);
-    }
+	public void setSingleImage(boolean noDeleteMode) {
+		mNoDeleteMode = noDeleteMode;
+		mInputProcessor.setCurrentSelectedSlot(0);
+	}
 
-    public MediaFeed getFeed() {
-        return mMediaFeed;
-    }
+	public MediaFeed getFeed() {
+		return mMediaFeed;
+	}
 
-    public void markDirty(int numFrames) {
-        mFramesDirty = numFrames;
-    }
+	public void markDirty(int numFrames) {
+		mFramesDirty = numFrames;
+	}
 
-    public void focusItem(String contentUri) {
-        mRequestFocusContentUri = contentUri;
-        mMediaFeed.updateListener(false);
-    }
+	public void focusItem(String contentUri) {
+		mRequestFocusContentUri = contentUri;
+		mMediaFeed.updateListener(false);
+	}
 
 }
diff --git a/src/com/cooliris/media/HudLayer.java b/src/com/cooliris/media/HudLayer.java
index e2d1bef..d7db544 100644
--- a/src/com/cooliris/media/HudLayer.java
+++ b/src/com/cooliris/media/HudLayer.java
@@ -396,6 +396,7 @@
 
     void setGridLayer(GridLayer layer) {
         mGridLayer = layer;
+        updateViews();
     }
 
     int getMode() {
@@ -754,7 +755,6 @@
     public void enterSelectionMode() {
         setAlpha(1.0f);
         setMode(HudLayer.MODE_SELECT);
-
         // if we are in single view mode, show the bottom menu without the delete button.
         if (mGridLayer.noDeleteMode()) {
             mSelectionMenuBottom.setMenus(mSingleViewIntentBottomMenu);
@@ -762,6 +762,22 @@
             mSelectionMenuBottom.setMenus(mNormalBottomMenu);
         }
     }
+    
+    public void computeBottomMenu() {
+    	// we need to the same for picasa albums
+        ArrayList<MediaBucket> selection = mGridLayer.getSelectedBuckets();
+        Menu[] menus = mSelectionMenuBottom.getMenus();
+        if (menus == mSingleViewIntentBottomMenu)
+        	return;
+        int numBuckets = selection.size();
+        for (int i = 0; i < numBuckets; ++i) {
+        	MediaBucket bucket = selection.get(i);
+        	if (bucket.mediaSet.mPicasaAlbumId != Shared.INVALID) {
+        		mSelectionMenuBottom.setMenus(mSingleViewIntentBottomMenu);
+        		break;
+        	}
+        }
+    }
 
     public Layer getMenuBar() {
         return mFullscreenMenu;
diff --git a/src/com/cooliris/media/LocalDataSource.java b/src/com/cooliris/media/LocalDataSource.java
index acd8d70..e6b89ac 100644
--- a/src/com/cooliris/media/LocalDataSource.java
+++ b/src/com/cooliris/media/LocalDataSource.java
@@ -32,6 +32,8 @@
     public static final String DOWNLOAD_BUCKET_NAME = Environment.getExternalStorageDirectory().toString() + "/" + DOWNLOAD_STRING;
     public static final int CAMERA_BUCKET_ID = getBucketId(CAMERA_BUCKET_NAME);
     public static final int DOWNLOAD_BUCKET_ID = getBucketId(DOWNLOAD_BUCKET_NAME);
+
+	public static boolean sObserverActive = false;
     private boolean mDisableImages;
     private boolean mDisableVideos;
 
@@ -43,8 +45,7 @@
     }
 
     private Context mContext;
-    private ContentObserver mImagesObserver;
-    private ContentObserver mVideosObserver;
+	private ContentObserver mObserver;
 
     public LocalDataSource(Context context) {
         mContext = context;
@@ -62,35 +63,29 @@
         stopListeners();
         CacheService.loadMediaSets(feed, this, !mDisableImages, !mDisableVideos);
         Handler handler = ((Gallery) mContext).getHandler();
-        ContentObserver imagesObserver = new ContentObserver(handler) {
+        ContentObserver observer = new ContentObserver(handler) {
             public void onChange(boolean selfChange) {
-                if (((Gallery) mContext).isPaused()) {
-                    refresh(feed, CAMERA_BUCKET_ID);
-                    refresh(feed, DOWNLOAD_BUCKET_ID);
-
-                    MediaSet set = feed.getCurrentSet();
-                    if (set != null && set.mPicasaAlbumId == Shared.INVALID) {
-                        refresh(feed, set.mId);
-                    }
-                }
+            	CacheService.senseDirty(mContext, new CacheService.Observer() {
+            		public void onChange(long[] ids) {
+            			if (ids != null) {
+            				int numLongs = ids.length;
+            				for (int i = 0; i < numLongs; ++i) {
+            					refreshUI(feed, ids[i]);
+            				}
+            			}
+            		}
+            	});
             }
         };
-        ContentObserver videosObserver = new ContentObserver(handler) {
-            public void onChange(boolean selfChange) {
-                if (((Gallery) mContext).isPaused()) {
-                    refresh(feed, CAMERA_BUCKET_ID);
-                }
-            }
-        };
-
-        // Start listening. TODO: coalesce update notifications while mediascanner is active.
+        
+        // Start listening.
         Uri uriImages = Images.Media.EXTERNAL_CONTENT_URI;
         Uri uriVideos = Video.Media.EXTERNAL_CONTENT_URI;
         ContentResolver cr = mContext.getContentResolver();
-        mImagesObserver = imagesObserver;
-        mVideosObserver = videosObserver;
-        cr.registerContentObserver(uriImages, false, mImagesObserver);
-        cr.registerContentObserver(uriVideos, false, mVideosObserver);
+        mObserver = observer;
+        cr.registerContentObserver(uriImages, false, observer);
+        cr.registerContentObserver(uriVideos, false, observer);
+        sObserverActive = true;
     }
 
     public void shutdown() {
@@ -101,23 +96,18 @@
     
     private void stopListeners() {
         ContentResolver cr = mContext.getContentResolver();
-        if (mImagesObserver != null) {
-            cr.unregisterContentObserver(mImagesObserver);
+        if (mObserver != null) {
+            cr.unregisterContentObserver(mObserver);
         }
-        if (mVideosObserver != null) {
-            cr.unregisterContentObserver(mVideosObserver);
-        }
+        sObserverActive = false;
     }
-
-    protected void refresh(MediaFeed feed, long setIdToUse) {
+    
+    protected void refreshUI(MediaFeed feed, long setIdToUse) {
         if (setIdToUse == Shared.INVALID) {
             return;
         }
         Log.i(TAG, "Refreshing local data source");
-        Gallery.NEEDS_REFRESH = true;
         if (feed.getMediaSet(setIdToUse) == null) {
-            if (!CacheService.setHasItems(mContext.getContentResolver(), setIdToUse))
-                return;
             MediaSet mediaSet = feed.addMediaSet(setIdToUse, this);
             if (setIdToUse == CAMERA_BUCKET_ID) {
                 mediaSet.mName = CAMERA_STRING;
@@ -125,8 +115,6 @@
                 mediaSet.mName = DOWNLOAD_STRING;
             }
             mediaSet.generateTitle(true);
-            if (!CacheService.isPresentInCache(setIdToUse))
-                CacheService.markDirty(mContext);
         } else {
             MediaSet mediaSet = feed.replaceMediaSet(setIdToUse, this);
             if (setIdToUse == CAMERA_BUCKET_ID) {
@@ -135,7 +123,6 @@
                 mediaSet.mName = DOWNLOAD_STRING;
             }
             mediaSet.generateTitle(true);
-            CacheService.markDirty(mContext, setIdToUse);
         }
     }
 
@@ -152,7 +139,7 @@
             return;
         }
         CacheService.loadMediaItemsIntoMediaFeed(mediaFeed, set, rangeStart, rangeEnd, !mDisableImages, !mDisableVideos);
-        if (set.mId == CAMERA_BUCKET_ID && set.mNumItemsLoaded > 0) {
+        if (set.mId == CAMERA_BUCKET_ID) {
             mediaFeed.moveSetToFront(set);
         }
     }
diff --git a/src/com/cooliris/media/MediaBucketList.java b/src/com/cooliris/media/MediaBucketList.java
index 3e0f568..773fefc 100644
--- a/src/com/cooliris/media/MediaBucketList.java
+++ b/src/com/cooliris/media/MediaBucketList.java
@@ -3,6 +3,7 @@
 import java.util.ArrayList;
 import java.util.HashMap;
 
+
 public final class MediaBucketList {
     private static final Boolean TRUE = new Boolean(true);
     private static final Boolean FALSE = new Boolean(false);
diff --git a/src/com/cooliris/media/PicasaDataSource.java b/src/com/cooliris/media/PicasaDataSource.java
index 0bd34ae..e3b9f87 100644
--- a/src/com/cooliris/media/PicasaDataSource.java
+++ b/src/com/cooliris/media/PicasaDataSource.java
@@ -30,14 +30,31 @@
     private ContentProviderClient mProviderClient;
     private final Context mContext;
     private ContentObserver mAlbumObserver;
-    private HashMap<String, Boolean> mAccountEnabled = new HashMap<String, Boolean>();
 
-    public PicasaDataSource(Context context) {
+    public PicasaDataSource(final Context context) {
         mContext = context;
     }
+    
+    public static final HashMap<String, Boolean> getAccountStatus(final Context context) {
+    	final Account[] accounts = PicasaApi.getAccounts(context);
+        int numAccounts = accounts.length;
+        HashMap<String, Boolean> accountsEnabled = new HashMap<String, Boolean>(numAccounts);
+        for (int i = 0; i < numAccounts; ++i) {
+            Account account = accounts[i];
+            boolean isEnabled = ContentResolver.getSyncAutomatically(account, PicasaContentProvider.AUTHORITY);
+            String username = account.name;
+            if (username.contains("@gmail.") || username.contains("@googlemail.")) {
+                // Strip the domain from GMail accounts for canonicalization. TODO: is there an official way?
+                username = username.substring(0, username.indexOf('@'));
+            }
+            accountsEnabled.put(username, new Boolean(isEnabled));
+        }
+        return accountsEnabled;
+    }
 
     public void loadMediaSets(final MediaFeed feed) {
-        if (mProviderClient == null) {
+        // We do this here and not in the constructor to speed application loading time since this method is called in a background thread
+    	if (mProviderClient == null) {
             mProviderClient = mContext.getContentResolver().acquireContentProviderClient(PicasaContentProvider.AUTHORITY);
         }
         // Force permission dialog to be displayed if necessary. TODO: remove this after signed by Google.
@@ -45,8 +62,8 @@
 
         // Ensure that users are up to date. TODO: also listen for accounts changed broadcast.
         PicasaService.requestSync(mContext, PicasaService.TYPE_USERS_ALBUMS, 0);
-        Handler handler = ((Gallery) mContext).getHandler();
-        ContentObserver albumObserver = new ContentObserver(handler) {
+        final Handler handler = ((Gallery) mContext).getHandler();
+        final ContentObserver albumObserver = new ContentObserver(handler) {
             public void onChange(boolean selfChange) {
                 loadMediaSetsIntoFeed(feed, true);
             }
@@ -77,34 +94,23 @@
     }
 
     protected void loadMediaSetsIntoFeed(final MediaFeed feed, boolean sync) {
-        Account[] accounts = PicasaApi.getAccounts(mContext);
-        int numAccounts = accounts.length;
-        for (int i = 0; i < numAccounts; ++i) {
-            Account account = accounts[i];
-            boolean isEnabled = ContentResolver.getSyncAutomatically(account, PicasaContentProvider.AUTHORITY);
-            String username = account.name;
-            if (username.contains("@gmail.") || username.contains("@googlemail.")) {
-                // Strip the domain from GMail accounts for canonicalization. TODO: is there an official way?
-                username = username.substring(0, username.indexOf('@'));
-            }
-            mAccountEnabled.put(username, new Boolean(isEnabled));
-        }
-        ContentProviderClient client = mProviderClient;
+        final HashMap<String, Boolean> accountsEnabled = getAccountStatus(mContext);
+        final ContentProviderClient client = mProviderClient;
         if (client == null)
             return;
         try {
-            EntrySchema albumSchema = AlbumEntry.SCHEMA;
-            Cursor cursor = client.query(PicasaContentProvider.ALBUMS_URI, albumSchema.getProjection(), null, null,
+            final EntrySchema albumSchema = AlbumEntry.SCHEMA;
+            final Cursor cursor = client.query(PicasaContentProvider.ALBUMS_URI, albumSchema.getProjection(), null, null,
                     DEFAULT_BUCKET_SORT_ORDER);
-            AlbumEntry album = new AlbumEntry();
+            final AlbumEntry album = new AlbumEntry();
             MediaSet mediaSet;
             if (cursor.moveToFirst()) {
-                int numAlbums = cursor.getCount();
-                ArrayList<MediaSet> picasaSets = new ArrayList<MediaSet>(numAlbums);
+                final int numAlbums = cursor.getCount();
+                final ArrayList<MediaSet> picasaSets = new ArrayList<MediaSet>(numAlbums);
                 do {
                     albumSchema.cursorToObject(cursor, album);
-                    Boolean accountEnabledObj = mAccountEnabled.get(album.user);
-                    boolean accountEnabled = (accountEnabledObj == null) ? false : accountEnabledObj.booleanValue();
+                    final Boolean accountEnabledObj = accountsEnabled.get(album.user);
+                    final boolean accountEnabled = (accountEnabledObj == null) ? false : accountEnabledObj.booleanValue();
                     if (accountEnabled) {
                         mediaSet = feed.getMediaSet(album.id);
                         if (mediaSet == null) {
@@ -128,14 +134,14 @@
     }
 
     private void addItemsToFeed(MediaFeed feed, MediaSet set, int start, int end) {
-        ContentProviderClient client = mProviderClient;
+        final ContentProviderClient client = mProviderClient;
         Cursor cursor = null;
         try {
             // Query photos in the album.
-            EntrySchema photosSchema = PhotoProjection.SCHEMA;
-            String whereInAlbum = "album_id = " + Long.toString(set.mId);
+            final EntrySchema photosSchema = PhotoProjection.SCHEMA;
+            final String whereInAlbum = "album_id = " + Long.toString(set.mId);
             cursor = client.query(PicasaContentProvider.PHOTOS_URI, photosSchema.getProjection(), whereInAlbum, null, null);
-            PhotoProjection photo = new PhotoProjection();
+            final PhotoProjection photo = new PhotoProjection();
             int count = cursor.getCount();
             if (count < end) {
                 end = count;
@@ -143,7 +149,7 @@
             set.setNumExpectedItems(count);
             set.generateTitle(true);
             // Move to the next unread item.
-            int newIndex = start + 1;
+            final int newIndex = start + 1;
             if (newIndex > count || !cursor.move(newIndex)) {
                 end = 0;
                 cursor.close();
@@ -161,7 +167,7 @@
             }
             for (int i = 0; i < end; ++i) {
                 photosSchema.cursorToObject(cursor, photo);
-                MediaItem item = new MediaItem();
+                final MediaItem item = new MediaItem();
                 item.mId = photo.id;
                 item.mEditUri = photo.editUri;
                 item.mMimeType = photo.contentType;
@@ -189,9 +195,6 @@
         }
     }
 
-    public void prime(final MediaItem item) {
-    }
-
     public boolean performOperation(final int operation, final ArrayList<MediaBucket> mediaBuckets, final Object data) {
         try {
             if (operation == MediaFeed.OPERATION_DELETE) {
diff --git a/src/com/cooliris/media/TimeBar.java b/src/com/cooliris/media/TimeBar.java
index 1fc4238..1b0184c 100644
--- a/src/com/cooliris/media/TimeBar.java
+++ b/src/com/cooliris/media/TimeBar.java
@@ -18,6 +18,7 @@
 import android.graphics.Rect;
 import android.util.SparseArray;
 import android.view.MotionEvent;
+
 import com.cooliris.media.RenderView.Lists;
 
 public final class TimeBar extends Layer implements MediaFeed.Listener {
