3rd party folders not appearing on resume Crash on computing sorted intersections We dont show location when location is not available in the details screen We dont stop slideshow when the volume keys or the notifications keys are fired Fixed bug with 3rd party folders not appearing on resume Crash on computing sorted intersections We dont show location when location is not available in the details screen We dont stop slideshow when the volume keys or the notifications keys are fired

Please enter the commit message for your changes. Lines starting
diff --git a/src/com/cooliris/cache/CacheService.java b/src/com/cooliris/cache/CacheService.java
index 68c4ea5..a3bd75c 100644
--- a/src/com/cooliris/cache/CacheService.java
+++ b/src/com/cooliris/cache/CacheService.java
@@ -14,12 +14,12 @@
 import java.text.ParseException;
 import java.text.SimpleDateFormat;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Date;
 import java.util.Locale;
 import java.util.concurrent.atomic.AtomicReference;
 
 import android.app.IntentService;
-import android.content.ContentProviderClient;
 import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
@@ -43,7 +43,6 @@
 import com.cooliris.media.DataSource;
 import com.cooliris.media.DiskCache;
 import com.cooliris.media.Gallery;
-import com.cooliris.media.ImageManager;
 import com.cooliris.media.LocalDataSource;
 import com.cooliris.media.LongSparseArray;
 import com.cooliris.media.MediaFeed;
@@ -199,6 +198,12 @@
 			QUEUE_DIRTY_SET = false;
 			restartThread(CACHE_THREAD, "CacheRefresh", new Runnable() {
 				public void run() {
+					try {
+						// We sleep for a bit here waiting for the provider database to insert the row(s).
+						// This should be unnecessary, and to be fixed in future versions.
+	                    Thread.sleep(100);
+                    } catch (InterruptedException e) {
+                    }
 					Log.i(TAG, "Computing dirty sets.");
 					long ids[] = computeDirtySets(context);
 					if (ids != null && observer != null) {
@@ -852,16 +857,6 @@
 		return C;
 	}
 
-	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);
-	}
-
 	private static final long[] toLongArray(final byte[] data) {
 		final ByteBuffer bBuffer = ByteBuffer.wrap(data);
 		final LongBuffer lBuffer = bBuffer.asLongBuffer();
@@ -988,22 +983,20 @@
 		cursors[0] = cursorImages;
 		cursors[1] = cursorVideos;
 		final MergeCursor cursor = new MergeCursor(cursors);
-		long[] retVal = null;
-		int ctr = 0;
+		ArrayList<Long> retVal = new ArrayList<Long>();
 		try {
 			if (cursor.moveToFirst()) {
-				retVal = new long[cursor.getCount()];
 				boolean allDirty = false;
 				do {
 					long setId = cursor.getLong(0);
 					if (allDirty) {
-						retVal[ctr++] = setId;
+						addNoDupe(retVal, setId);
 					} else {
 						boolean contains = sAlbumCache.isDataAvailable(setId, 0);
 						if (!contains) {
 							// We need to refresh everything.
 							markDirty(context);
-							retVal[ctr++] = setId;
+							addNoDupe(retVal, setId);
 							allDirty = true;
 						}
 						if (!allDirty) {
@@ -1016,10 +1009,9 @@
 							}
 							long oldMaxAdded = dataLong[0];
 							long oldCount = dataLong[1];
-							Log.i(TAG, "Bucket " + setId + " Old added " + oldMaxAdded + " count " + oldCount + " New added " + maxAdded + " count " + count);
 							if (maxAdded > oldMaxAdded || oldCount != count) {
 								markDirty(context, setId);
-								retVal[ctr++] = setId;
+								addNoDupe(retVal, setId);
 								dataLong[0] = maxAdded;
 								dataLong[1] = count;
 								sMetaAlbumCache.put(setId, longArrayToByteArray(dataLong));
@@ -1033,11 +1025,21 @@
 		}
 		sMetaAlbumCache.flush();
 		processQueuedDirty(context);
-		long[] retValCompact = new long[ctr];
-		for (int i = 0; i < ctr; ++i) {
-			retValCompact[i] = retVal[i];
+		int numIds = retVal.size();
+		long retValIds[] = new long[retVal.size()];
+		for (int i = 0; i < numIds; ++i) {
+			retValIds[i] = retVal.get(i);
 		}
-		return retValCompact;
+		return retValIds;
+	}
+	
+	private static final void addNoDupe(ArrayList<Long> array, long value) {
+		int size = array.size();
+		for (int i = 0; i < size; ++i) {
+			if (array.get(i).longValue() == value)
+				return;
+		}
+		array.add(value);
 	}
 
 	private static final void processQueuedDirty(final Context context) {
diff --git a/src/com/cooliris/media/ArrayUtils.java b/src/com/cooliris/media/ArrayUtils.java
index 29a4f32..4f7e11e 100644
--- a/src/com/cooliris/media/ArrayUtils.java
+++ b/src/com/cooliris/media/ArrayUtils.java
@@ -21,6 +21,8 @@
         int firstListSize = firstList.size();
         for (int i = 0; i < firstListSize; ++i) {
             MediaItem firstListItem = firstList.get(i);
+            if (firstListItem == null)
+            	continue;
             MediaItem hashItem = (hash != null) ? hash[firstListItem.hashCode() & mask] : null;
             if (hashItem != null && ((hashItem.mId != Shared.INVALID && hashItem.mId == firstListItem.mId) || contains(secondList, firstListItem))) {
                 intersectionList.add(firstListItem);
diff --git a/src/com/cooliris/media/DetailMode.java b/src/com/cooliris/media/DetailMode.java
index cf78a58..10c06c1 100644
--- a/src/com/cooliris/media/DetailMode.java
+++ b/src/com/cooliris/media/DetailMode.java
@@ -48,21 +48,21 @@
             return null;
         }
         Resources resources = context.getResources();
-        CharSequence[] strings = new CharSequence[5];
-
+        ArrayList<CharSequence> strings = new ArrayList<CharSequence>();
+        
         // Number of albums selected.
         if (numOriginalSets == 1) {
-            strings[0] = "1 " + resources.getString(R.string.album_selected);
+            strings.add("1 " + resources.getString(R.string.album_selected));
         } else {
-            strings[0] = Integer.toString(numOriginalSets) + " " + resources.getString(R.string.albums_selected);
+            strings.add(Integer.toString(numOriginalSets) + " " + resources.getString(R.string.albums_selected));
         }
 
         // Number of items selected.
         int numItems = selectedItemsSet.mNumItemsLoaded;
         if (numItems == 1) {
-            strings[1] = "1 " + resources.getString(R.string.item_selected);
+            strings.add("1 " + resources.getString(R.string.item_selected));
         } else {
-            strings[1] = Integer.toString(numItems) + " " + resources.getString(R.string.items_selected);
+            strings.add(Integer.toString(numItems) + " " + resources.getString(R.string.items_selected));
         }
         
         DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM,DateFormat.SHORT);
@@ -75,8 +75,8 @@
                 minTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(minTimestamp);
                 maxTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(maxTimestamp);
             }
-            strings[2] = resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp));
-            strings[3] = resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp));
+            strings.add(resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp)));
+            strings.add(resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp)));
         } else if (selectedItemsSet.areAddedTimestampsAvailable()) {
             long minTimestamp = selectedItemsSet.mMinAddedTimestamp;
             long maxTimestamp = selectedItemsSet.mMaxAddedTimestamp;
@@ -84,11 +84,11 @@
                 minTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(minTimestamp);
                 maxTimestamp -= Gallery.CURRENT_TIME_ZONE.getOffset(maxTimestamp);
             }
-            strings[2] = resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp));
-            strings[3] = resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp));            
+            strings.add(resources.getString(R.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp)));
+            strings.add(resources.getString(R.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp)));            
         } else {
-            strings[2] = resources.getString(R.string.start) + ": " + resources.getString(R.string.date_unknown);
-            strings[3] = resources.getString(R.string.end) + ": " + resources.getString(R.string.date_unknown);
+            strings.add(resources.getString(R.string.start) + ": " + resources.getString(R.string.date_unknown));
+            strings.add(resources.getString(R.string.end) + ": " + resources.getString(R.string.date_unknown));
         }
 
         // The location of the selected items.
@@ -101,11 +101,15 @@
                 locationString = reverseGeocoder.computeMostGranularCommonLocation(selectedItemsSet);
             }
         }
-        if (locationString == null || locationString.length() == 0) {
-            locationString = resources.getString(R.string.location_unknown);
+        if (locationString != null && locationString.length() > 0) {
+        	strings.add(resources.getString(R.string.location) + ": " + locationString);
         }
-        strings[4] = resources.getString(R.string.location) + ": " + locationString;
-        return strings;
+        int numStrings = strings.size();
+        CharSequence[] stringsArr = new CharSequence[numStrings];
+        for (int i = 0; i < numStrings; ++i) {
+        	stringsArr[i] = strings.get(i);
+        }
+        return stringsArr;
     }
 
     private static CharSequence[] populateItemViewDetailModeStrings(Context context, MediaItem item) {
diff --git a/src/com/cooliris/media/Gallery.java b/src/com/cooliris/media/Gallery.java
index dcadb4d..e0a5ab1 100644
--- a/src/com/cooliris/media/Gallery.java
+++ b/src/com/cooliris/media/Gallery.java
@@ -76,7 +76,7 @@
 		mRenderView.setRootLayer(mGridLayer);
 		setContentView(mRenderView);
 		
-		// Creating the DataSource objects
+		// Creating the DataSource objects.
 		final PicasaDataSource picasaDataSource = new PicasaDataSource(this);
 		final LocalDataSource localDataSource = new LocalDataSource(this);
 		final ConcatenatedDataSource combinedDataSource = new ConcatenatedDataSource(localDataSource, picasaDataSource);
diff --git a/src/com/cooliris/media/GridInputProcessor.java b/src/com/cooliris/media/GridInputProcessor.java
index 94a15d8..12b7032 100644
--- a/src/com/cooliris/media/GridInputProcessor.java
+++ b/src/com/cooliris/media/GridInputProcessor.java
@@ -5,670 +5,671 @@
 import android.hardware.SensorEvent;
 import android.os.SystemClock;
 import android.view.GestureDetector;
-import android.view.HapticFeedbackConstants;
 import android.view.KeyEvent;
 import android.view.MotionEvent;
 
 public final class GridInputProcessor implements GestureDetector.OnGestureListener, GestureDetector.OnDoubleTapListener {
-    private int mCurrentFocusSlot;
-    private boolean mCurrentFocusIsPressed;
-    private int mCurrentSelectedSlot;
+	private int mCurrentFocusSlot;
+	private boolean mCurrentFocusIsPressed;
+	private int mCurrentSelectedSlot;
 
-    private float mPrevTiltValueLowPass;
-    private float mPrevShakeValueHighPass;
-    private float mShakeValue;
-    private int mTouchPosX;
-    private int mTouchPosY;
-    private int mActionCode;
-    private long mPrevTouchTime;
-    private float mFirstTouchPosX;
-    private float mFirstTouchPosY;
-    private float mPrevTouchPosX;
-    private float mPrevTouchPosY;
-    private float mTouchVelX;
-    private float mTouchVelY;
-    private boolean mProcessTouch;
-    private boolean mTouchMoved;
-    private float mDpadIgnoreTime = 0.0f;
-    private GridCamera mCamera;
-    private GridLayer mLayer;
-    private Context mContext;
-    private Pool<Vector3f> mPool;
-    private DisplayItem[] mDisplayItems;
-    private boolean mPrevHitEdge;
-    private boolean mTouchFeedbackDelivered;
-    private GestureDetector mGestureDetector;
-    private RenderView mView;
+	private float mPrevTiltValueLowPass;
+	private float mPrevShakeValueHighPass;
+	private float mShakeValue;
+	private int mTouchPosX;
+	private int mTouchPosY;
+	private int mActionCode;
+	private long mPrevTouchTime;
+	private float mFirstTouchPosX;
+	private float mFirstTouchPosY;
+	private float mPrevTouchPosX;
+	private float mPrevTouchPosY;
+	private float mTouchVelX;
+	private float mTouchVelY;
+	private boolean mProcessTouch;
+	private boolean mTouchMoved;
+	private float mDpadIgnoreTime = 0.0f;
+	private GridCamera mCamera;
+	private GridLayer mLayer;
+	private Context mContext;
+	private Pool<Vector3f> mPool;
+	private DisplayItem[] mDisplayItems;
+	private boolean mPrevHitEdge;
+	private boolean mTouchFeedbackDelivered;
+	private GestureDetector mGestureDetector;
 
-    public GridInputProcessor(Context context, GridCamera camera, GridLayer layer, RenderView view, Pool<Vector3f> pool,
-            DisplayItem[] displayItems) {
-        mPool = pool;
-        mCamera = camera;
-        mLayer = layer;
-        mCurrentFocusSlot = Shared.INVALID;
-        mCurrentSelectedSlot = Shared.INVALID;
-        mContext = context;
-        mDisplayItems = displayItems;
-        mGestureDetector = new GestureDetector(context, this);
-        mGestureDetector.setIsLongpressEnabled(true);
-        mView = view;
-    }
+	public GridInputProcessor(Context context, GridCamera camera, GridLayer layer, RenderView view, Pool<Vector3f> pool,
+	        DisplayItem[] displayItems) {
+		mPool = pool;
+		mCamera = camera;
+		mLayer = layer;
+		mCurrentFocusSlot = Shared.INVALID;
+		mCurrentSelectedSlot = Shared.INVALID;
+		mContext = context;
+		mDisplayItems = displayItems;
+		mGestureDetector = new GestureDetector(context, this);
+		mGestureDetector.setIsLongpressEnabled(true);
+	}
 
-    public int getCurrentFocusSlot() {
-        return mCurrentFocusSlot;
-    }
+	public int getCurrentFocusSlot() {
+		return mCurrentFocusSlot;
+	}
 
-    public int getCurrentSelectedSlot() {
-        return mCurrentSelectedSlot;
-    }
+	public int getCurrentSelectedSlot() {
+		return mCurrentSelectedSlot;
+	}
 
-    public void setCurrentSelectedSlot(int slot) {
-        mCurrentSelectedSlot = slot;
-        GridLayer layer = mLayer;
-        layer.setState(GridLayer.STATE_FULL_SCREEN);
-        mCamera.mConvergenceSpeed = 2.0f;
-        DisplayItem displayItem = layer.getDisplayItemForSlotId(slot);
-        MediaItem item = null;
-        if (displayItem != null)
-            item = displayItem.mItemRef;
-        layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
-    }
+	public void setCurrentSelectedSlot(int slot) {
+		mCurrentSelectedSlot = slot;
+		GridLayer layer = mLayer;
+		layer.setState(GridLayer.STATE_FULL_SCREEN);
+		mCamera.mConvergenceSpeed = 2.0f;
+		DisplayItem displayItem = layer.getDisplayItemForSlotId(slot);
+		MediaItem item = null;
+		if (displayItem != null)
+			item = displayItem.mItemRef;
+		layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
+	}
 
-    public void onSensorChanged(RenderView view, SensorEvent event, int state) {
-        switch (event.sensor.getType()) {
-        case Sensor.TYPE_ACCELEROMETER:
-        case Sensor.TYPE_ORIENTATION:
-            float[] values = event.values;
-            float valueToUse = (mCamera.mWidth < mCamera.mHeight) ? values[0] : -values[1];
-            float tiltValue = 0.8f * mPrevTiltValueLowPass + 0.2f * valueToUse;
-            if (Math.abs(tiltValue) < 0.5f)
-                tiltValue = 0.0f;
-            if (state == GridLayer.STATE_FULL_SCREEN)
-                tiltValue = 0.0f;
-            if (tiltValue != 0.0f)
-                view.requestRender();
-            mCamera.mEyeOffsetX = -3.0f * tiltValue;
-            float shakeValue = values[1] * values[1] + values[2] * values[2];
-            mShakeValue = shakeValue - mPrevShakeValueHighPass;
-            mPrevShakeValueHighPass = shakeValue;
-            if (mShakeValue < 16.0f) {
-                mShakeValue = 0;
-            } else {
-                mShakeValue = mShakeValue * 4.0f;
-                if (mShakeValue > 200) {
-                    mShakeValue = 200;
-                }
-            }
-            break;
-        }
-    }
+	public void onSensorChanged(RenderView view, SensorEvent event, int state) {
+		switch (event.sensor.getType()) {
+		case Sensor.TYPE_ACCELEROMETER:
+		case Sensor.TYPE_ORIENTATION:
+			float[] values = event.values;
+			float valueToUse = (mCamera.mWidth < mCamera.mHeight) ? values[0] : -values[1];
+			float tiltValue = 0.8f * mPrevTiltValueLowPass + 0.2f * valueToUse;
+			if (Math.abs(tiltValue) < 0.5f)
+				tiltValue = 0.0f;
+			if (state == GridLayer.STATE_FULL_SCREEN)
+				tiltValue = 0.0f;
+			if (tiltValue != 0.0f)
+				view.requestRender();
+			mCamera.mEyeOffsetX = -3.0f * tiltValue;
+			float shakeValue = values[1] * values[1] + values[2] * values[2];
+			mShakeValue = shakeValue - mPrevShakeValueHighPass;
+			mPrevShakeValueHighPass = shakeValue;
+			if (mShakeValue < 16.0f) {
+				mShakeValue = 0;
+			} else {
+				mShakeValue = mShakeValue * 4.0f;
+				if (mShakeValue > 200) {
+					mShakeValue = 200;
+				}
+			}
+			break;
+		}
+	}
 
-    public boolean onTouchEvent(MotionEvent event) {
-        mTouchPosX = (int) (event.getX());
-        mTouchPosY = (int) (event.getY());
-        mActionCode = event.getAction();
-        long timestamp = SystemClock.elapsedRealtime();
-        long delta = timestamp - mPrevTouchTime;
-        mPrevTouchTime = timestamp;
-        float timeElapsed = (float) delta;
-        timeElapsed = timeElapsed * 0.001f; // division by 1000 for seconds
-        switch (mActionCode) {
-        case MotionEvent.ACTION_UP:
-            if (mProcessTouch == false) {
-                touchBegan(mTouchPosX, mTouchPosY);
-            }
-            touchEnded(mTouchPosX, mTouchPosY, timeElapsed);
-            break;
-        case MotionEvent.ACTION_DOWN:
-            mPrevTouchTime = timestamp;
-            touchBegan(mTouchPosX, mTouchPosY);
-            break;
-        case MotionEvent.ACTION_MOVE:
-            touchMoved(mTouchPosX, mTouchPosY, timeElapsed);
-            break;
-        }
-        mGestureDetector.onTouchEvent(event);
-        return true;
-    }
+	public boolean onTouchEvent(MotionEvent event) {
+		mTouchPosX = (int) (event.getX());
+		mTouchPosY = (int) (event.getY());
+		mActionCode = event.getAction();
+		long timestamp = SystemClock.elapsedRealtime();
+		long delta = timestamp - mPrevTouchTime;
+		mPrevTouchTime = timestamp;
+		float timeElapsed = (float) delta;
+		timeElapsed = timeElapsed * 0.001f; // division by 1000 for seconds
+		switch (mActionCode) {
+		case MotionEvent.ACTION_UP:
+			if (mProcessTouch == false) {
+				touchBegan(mTouchPosX, mTouchPosY);
+			}
+			touchEnded(mTouchPosX, mTouchPosY, timeElapsed);
+			break;
+		case MotionEvent.ACTION_DOWN:
+			mPrevTouchTime = timestamp;
+			touchBegan(mTouchPosX, mTouchPosY);
+			break;
+		case MotionEvent.ACTION_MOVE:
+			touchMoved(mTouchPosX, mTouchPosY, timeElapsed);
+			break;
+		}
+		mGestureDetector.onTouchEvent(event);
+		return true;
+	}
 
-    public boolean onKeyDown(int keyCode, KeyEvent event, int state) {
-        GridLayer layer = mLayer;
-        if (keyCode == KeyEvent.KEYCODE_BACK) {
-            if (layer.getViewIntent())
-                return false;
-            if (layer.getHud().getMode() == HudLayer.MODE_SELECT) {
-                layer.deselectAll();
-                return true;
-            }
-            if (layer.inSlideShowMode()) {
-                layer.endSlideshow();
-                layer.getHud().setAlpha(1.0f);
-                return true;
-            }
-            float zoomValue = layer.getZoomValue();
-            if (zoomValue != 1.0f) {
-                layer.setZoomValue(1.0f);
-                layer.centerCameraForSlot(mCurrentSelectedSlot, 1.0f);
-                return true;
-            }
-            layer.goBack();
-            if (state == GridLayer.STATE_MEDIA_SETS)
-                return false;
-            return true;
-        }
-        if (mDpadIgnoreTime < 0.1f)
-            return true;
-        mDpadIgnoreTime = 0.0f;
-        IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
-        int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
-        int lastBufferedVisibleSlot = bufferedVisibleRange.end;
-        int anchorSlot = layer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER);
-        if (state == GridLayer.STATE_FULL_SCREEN) {
-            layer.endSlideshow();
-            boolean needsVibrate = false;
-            if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
-                needsVibrate = !layer.changeFocusToNextSlot(1.0f);
-            }
-            if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
-                needsVibrate = !layer.changeFocusToPreviousSlot(1.0f);
-            }
-            if (needsVibrate) {
-                vibrateShort();
-            }
-            if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && !mCamera.isAnimating()) {
-                if (layer.getZoomValue() == 1.0f)
-                    layer.zoomInToSelectedItem();
-                else
-                    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
-                    layer.deselectAll();
-            }
-        } else {
-            mCurrentFocusIsPressed = false;
-            int numRows = ((GridLayoutInterface) layer.getLayoutInterface()).mNumRows;
-            if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && mCurrentFocusSlot != Shared.INVALID) {
-                if (layer.getHud().getMode() != HudLayer.MODE_SELECT) {
-                    boolean centerCamera = layer.tapGesture(mCurrentFocusSlot, false);
-                    if (centerCamera) {
-                        int slotId = mCurrentFocusSlot;
-                        selectSlot(slotId);
-                    }
-                    mCurrentFocusSlot = Shared.INVALID;
-                    return true;
-                } else {
-                    layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
-                }
-                mCurrentFocusIsPressed = true;
-            } else if (keyCode == KeyEvent.KEYCODE_MENU && mCurrentFocusSlot != Shared.INVALID) {
-                if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
-                    layer.enterSelectionMode();
-                else
-                    layer.deselectAll();
-            } else if (mCurrentFocusSlot == Shared.INVALID) {
-                mCurrentFocusSlot = anchorSlot;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
-                mCurrentFocusSlot += numRows;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
-                mCurrentFocusSlot -= numRows;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
-                --mCurrentFocusSlot;
-            } else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
-                ++mCurrentFocusSlot;
-            }
-            if (mCurrentFocusSlot > lastBufferedVisibleSlot) {
-                mCurrentFocusSlot = lastBufferedVisibleSlot;
-            }
-            if (mCurrentFocusSlot < firstBufferedVisibleSlot)
-                mCurrentFocusSlot = firstBufferedVisibleSlot;
-            if (mCurrentFocusSlot != Shared.INVALID) {
-                layer.centerCameraForSlot(mCurrentFocusSlot, 1.0f);
-            }
-        }
-        return false;
-    }
+	public boolean onKeyDown(int keyCode, KeyEvent event, int state) {
+		GridLayer layer = mLayer;
+		if (keyCode == KeyEvent.KEYCODE_BACK) {
+			if (layer.getViewIntent())
+				return false;
+			if (layer.getHud().getMode() == HudLayer.MODE_SELECT) {
+				layer.deselectAll();
+				return true;
+			}
+			if (layer.inSlideShowMode()) {
+				layer.endSlideshow();
+				layer.getHud().setAlpha(1.0f);
+				return true;
+			}
+			float zoomValue = layer.getZoomValue();
+			if (zoomValue != 1.0f) {
+				layer.setZoomValue(1.0f);
+				layer.centerCameraForSlot(mCurrentSelectedSlot, 1.0f);
+				return true;
+			}
+			layer.goBack();
+			if (state == GridLayer.STATE_MEDIA_SETS)
+				return false;
+			return true;
+		}
+		if (mDpadIgnoreTime < 0.1f)
+			return true;
+		mDpadIgnoreTime = 0.0f;
+		IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
+		int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
+		int lastBufferedVisibleSlot = bufferedVisibleRange.end;
+		int anchorSlot = layer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER);
+		if (state == GridLayer.STATE_FULL_SCREEN) {
+			if (keyCode != KeyEvent.KEYCODE_VOLUME_UP && keyCode != KeyEvent.KEYCODE_VOLUME_DOWN
+			        && keyCode != KeyEvent.KEYCODE_MUTE && keyCode != KeyEvent.KEYCODE_HEADSETHOOK
+			        && keyCode != KeyEvent.KEYCODE_NOTIFICATION) {
+				layer.endSlideshow();
+			}
+			boolean needsVibrate = false;
+			if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+				needsVibrate = !layer.changeFocusToNextSlot(1.0f);
+			}
+			if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+				needsVibrate = !layer.changeFocusToPreviousSlot(1.0f);
+			}
+			if (needsVibrate) {
+				vibrateShort();
+			}
+			if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && !mCamera.isAnimating()) {
+				if (layer.getZoomValue() == 1.0f)
+					layer.zoomInToSelectedItem();
+				else
+					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
+					layer.deselectAll();
+			}
+		} else {
+			mCurrentFocusIsPressed = false;
+			int numRows = ((GridLayoutInterface) layer.getLayoutInterface()).mNumRows;
+			if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER && mCurrentFocusSlot != Shared.INVALID) {
+				if (layer.getHud().getMode() != HudLayer.MODE_SELECT) {
+					boolean centerCamera = layer.tapGesture(mCurrentFocusSlot, false);
+					if (centerCamera) {
+						int slotId = mCurrentFocusSlot;
+						selectSlot(slotId);
+					}
+					mCurrentFocusSlot = Shared.INVALID;
+					return true;
+				} else {
+					layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
+				}
+				mCurrentFocusIsPressed = true;
+			} else if (keyCode == KeyEvent.KEYCODE_MENU && mCurrentFocusSlot != Shared.INVALID) {
+				if (layer.getHud().getMode() == HudLayer.MODE_NORMAL)
+					layer.enterSelectionMode();
+				else
+					layer.deselectAll();
+			} else if (mCurrentFocusSlot == Shared.INVALID) {
+				mCurrentFocusSlot = anchorSlot;
+			} else if (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT) {
+				mCurrentFocusSlot += numRows;
+			} else if (keyCode == KeyEvent.KEYCODE_DPAD_LEFT) {
+				mCurrentFocusSlot -= numRows;
+			} else if (keyCode == KeyEvent.KEYCODE_DPAD_UP) {
+				--mCurrentFocusSlot;
+			} else if (keyCode == KeyEvent.KEYCODE_DPAD_DOWN) {
+				++mCurrentFocusSlot;
+			}
+			if (mCurrentFocusSlot > lastBufferedVisibleSlot) {
+				mCurrentFocusSlot = lastBufferedVisibleSlot;
+			}
+			if (mCurrentFocusSlot < firstBufferedVisibleSlot)
+				mCurrentFocusSlot = firstBufferedVisibleSlot;
+			if (mCurrentFocusSlot != Shared.INVALID) {
+				layer.centerCameraForSlot(mCurrentFocusSlot, 1.0f);
+			}
+		}
+		return false;
+	}
 
-    private void touchBegan(int posX, int posY) {
-        mPrevTouchPosX = posX;
-        mPrevTouchPosY = posY;
-        mFirstTouchPosX = posX;
-        mFirstTouchPosY = posY;
-        mTouchVelX = 0;
-        mTouchVelY = 0;
-        mProcessTouch = true;
-        mTouchMoved = false;
-        mCamera.stopMovementInX();
-        GridLayer layer = mLayer;
-        mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
-        mCurrentFocusIsPressed = true;
-        mTouchFeedbackDelivered = false;
-        HudLayer hud = layer.getHud();
-        if (hud.getMode() == HudLayer.MODE_SELECT)
-            hud.closeSelectionMenu();
-        if (layer.getState() == GridLayer.STATE_FULL_SCREEN && hud.getMode() == HudLayer.MODE_SELECT) {
-            layer.deselectAll();
-            hud.setAlpha(1.0f);
-        }
-        int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
-        if (slotId != Shared.INVALID && layer.getState() != GridLayer.STATE_FULL_SCREEN) {
-            vibrateShort();
-        }
-    }
+	private void touchBegan(int posX, int posY) {
+		mPrevTouchPosX = posX;
+		mPrevTouchPosY = posY;
+		mFirstTouchPosX = posX;
+		mFirstTouchPosY = posY;
+		mTouchVelX = 0;
+		mTouchVelY = 0;
+		mProcessTouch = true;
+		mTouchMoved = false;
+		mCamera.stopMovementInX();
+		GridLayer layer = mLayer;
+		mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
+		mCurrentFocusIsPressed = true;
+		mTouchFeedbackDelivered = false;
+		HudLayer hud = layer.getHud();
+		if (hud.getMode() == HudLayer.MODE_SELECT)
+			hud.closeSelectionMenu();
+		if (layer.getState() == GridLayer.STATE_FULL_SCREEN && hud.getMode() == HudLayer.MODE_SELECT) {
+			layer.deselectAll();
+			hud.setAlpha(1.0f);
+		}
+		int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
+		if (slotId != Shared.INVALID && layer.getState() != GridLayer.STATE_FULL_SCREEN) {
+			vibrateShort();
+		}
+	}
 
-    private void touchMoved(int posX, int posY, float timeElapsedx) {
-        if (mProcessTouch) {
-            GridLayer layer = mLayer;
-            GridCamera camera = mCamera;
-            float deltaX = -(posX - mPrevTouchPosX); // negation since the wall
-            // moves in a direction
-            // opposite to that of
-            // the touch
-            float deltaY = -(posY - mPrevTouchPosY);
-            if (Math.abs(deltaX) >= 10.0f || Math.abs(deltaY) >= 10.0f) {
-                mTouchMoved = true;
-            }
-            Pool<Vector3f> pool = mPool;
-            Vector3f firstPosition = pool.create();
-            Vector3f lastPosition = pool.create();
-            Vector3f deltaAnchorPosition = pool.create();
-            Vector3f worldPosDelta = pool.create();
-            try {
-                deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
-                LayoutInterface layout = layer.getLayoutInterface();
-                GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
-                int lastSlotIndex = 0;
-                IndexRange completeRange = layer.getCompleteRange();
-                synchronized (completeRange) {
-                    lastSlotIndex = completeRange.end;
-                }
-                GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
+	private void touchMoved(int posX, int posY, float timeElapsedx) {
+		if (mProcessTouch) {
+			GridLayer layer = mLayer;
+			GridCamera camera = mCamera;
+			float deltaX = -(posX - mPrevTouchPosX); // negation since the wall
+			// moves in a direction
+			// opposite to that of
+			// the touch
+			float deltaY = -(posY - mPrevTouchPosY);
+			if (Math.abs(deltaX) >= 10.0f || Math.abs(deltaY) >= 10.0f) {
+				mTouchMoved = true;
+			}
+			Pool<Vector3f> pool = mPool;
+			Vector3f firstPosition = pool.create();
+			Vector3f lastPosition = pool.create();
+			Vector3f deltaAnchorPosition = pool.create();
+			Vector3f worldPosDelta = pool.create();
+			try {
+				deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
+				LayoutInterface layout = layer.getLayoutInterface();
+				GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
+				int lastSlotIndex = 0;
+				IndexRange completeRange = layer.getCompleteRange();
+				synchronized (completeRange) {
+					lastSlotIndex = completeRange.end;
+				}
+				GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
 
-                camera.convertToRelativeCameraSpace(deltaX, deltaY, 0, worldPosDelta);
-                deltaX = worldPosDelta.x;
-                deltaY = worldPosDelta.y;
-                camera.moveBy(deltaX, (layer.getZoomValue() == 1.0f) ? 0 : deltaY, 0);
-                deltaX *= camera.mScale;
-                deltaY *= camera.mScale;
-            } finally {
-                pool.delete(firstPosition);
-                pool.delete(lastPosition);
-                pool.delete(deltaAnchorPosition);
-                pool.delete(worldPosDelta);
-            }
-            if (layer.getZoomValue() == 1.0f) {
-                if (camera
-                        .computeConstraints(false, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition)) {
-                    deltaX = 0.0f;
-                    // vibrate
-                    if (!mTouchFeedbackDelivered) {
-                        mTouchFeedbackDelivered = true;
-                        vibrateLong();
-                    }
-                }
-            }
-            mTouchVelX = deltaX * timeElapsedx;
-            mTouchVelY = deltaY * timeElapsedx;
-            float maxVelXx = (mCamera.mWidth * 0.5f);
-            float maxVelYx = (mCamera.mHeight);
-            mTouchVelX = FloatUtils.clamp(mTouchVelX, -maxVelXx, maxVelXx);
-            mTouchVelY = FloatUtils.clamp(mTouchVelY, -maxVelYx, maxVelYx);
-            mPrevTouchPosX = posX;
-            mPrevTouchPosY = posY;
-            // you want the movement to track the finger immediately
-            if (mTouchMoved == false)
-                mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
-            else
-                mCurrentFocusSlot = Shared.INVALID;
-            if (!mCamera.isZAnimating()) {
-                mCamera.commitMoveInX();
-                mCamera.commitMoveInY();
-            }
-            int anchorSlotIndex = layer.getAnchorSlotIndex(GridLayer.ANCHOR_LEFT);
-            DisplayItem[] displayItems = mDisplayItems;
-            IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
-            int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
-            int lastBufferedVisibleSlot = bufferedVisibleRange.end;
-            synchronized (displayItems) {
-                if (anchorSlotIndex >= firstBufferedVisibleSlot && anchorSlotIndex <= lastBufferedVisibleSlot) {
-                    DisplayItem item = displayItems[(anchorSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
-                    if (item != null) {
-                        layer.getHud().setTimeBarTime(item.mItemRef.mDateTakenInMs);
-                    }
-                }
-            }
-        }
-    }
+				camera.convertToRelativeCameraSpace(deltaX, deltaY, 0, worldPosDelta);
+				deltaX = worldPosDelta.x;
+				deltaY = worldPosDelta.y;
+				camera.moveBy(deltaX, (layer.getZoomValue() == 1.0f) ? 0 : deltaY, 0);
+				deltaX *= camera.mScale;
+				deltaY *= camera.mScale;
+			} finally {
+				pool.delete(firstPosition);
+				pool.delete(lastPosition);
+				pool.delete(deltaAnchorPosition);
+				pool.delete(worldPosDelta);
+			}
+			if (layer.getZoomValue() == 1.0f) {
+				if (camera
+				        .computeConstraints(false, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition)) {
+					deltaX = 0.0f;
+					// vibrate
+					if (!mTouchFeedbackDelivered) {
+						mTouchFeedbackDelivered = true;
+						vibrateLong();
+					}
+				}
+			}
+			mTouchVelX = deltaX * timeElapsedx;
+			mTouchVelY = deltaY * timeElapsedx;
+			float maxVelXx = (mCamera.mWidth * 0.5f);
+			float maxVelYx = (mCamera.mHeight);
+			mTouchVelX = FloatUtils.clamp(mTouchVelX, -maxVelXx, maxVelXx);
+			mTouchVelY = FloatUtils.clamp(mTouchVelY, -maxVelYx, maxVelYx);
+			mPrevTouchPosX = posX;
+			mPrevTouchPosY = posY;
+			// you want the movement to track the finger immediately
+			if (mTouchMoved == false)
+				mCurrentFocusSlot = layer.getSlotIndexForScreenPosition(posX, posY);
+			else
+				mCurrentFocusSlot = Shared.INVALID;
+			if (!mCamera.isZAnimating()) {
+				mCamera.commitMoveInX();
+				mCamera.commitMoveInY();
+			}
+			int anchorSlotIndex = layer.getAnchorSlotIndex(GridLayer.ANCHOR_LEFT);
+			DisplayItem[] displayItems = mDisplayItems;
+			IndexRange bufferedVisibleRange = layer.getBufferedVisibleRange();
+			int firstBufferedVisibleSlot = bufferedVisibleRange.begin;
+			int lastBufferedVisibleSlot = bufferedVisibleRange.end;
+			synchronized (displayItems) {
+				if (anchorSlotIndex >= firstBufferedVisibleSlot && anchorSlotIndex <= lastBufferedVisibleSlot) {
+					DisplayItem item = displayItems[(anchorSlotIndex - firstBufferedVisibleSlot) * GridLayer.MAX_ITEMS_PER_SLOT];
+					if (item != null) {
+						layer.getHud().setTimeBarTime(item.mItemRef.mDateTakenInMs);
+					}
+				}
+			}
+		}
+	}
 
-    private void touchEnded(int posX, int posY, float timeElapsedx) {
-        if (mProcessTouch == false)
-            return;
-        int maxPixelsBeforeSwitch = mCamera.mWidth / 8;
-        mCamera.mConvergenceSpeed = 2.0f;
-        GridLayer layer = mLayer;
-        if (layer.getExpandedSlot() == Shared.INVALID && !layer.feedAboutToChange()) {
-            if (mCurrentSelectedSlot != Shared.INVALID) {
-                if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
-                    if (!mTouchMoved) {
-                        // tap gesture for fullscreen
-                        if (layer.getZoomValue() == 1.0f)
-                            layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
-                    } else if (layer.getZoomValue() == 1.0f) {
-                        // we want to snap to a new slotIndex based on where the
-                        // current position is
-                        if (layer.inSlideShowMode()) {
-                            layer.endSlideshow();
-                        }
-                        float deltaX = posX - mFirstTouchPosX;
-                        float deltaY = posY - mFirstTouchPosY;
-                        if (deltaY != 0) {
-                            // it has moved vertically
-                        }
-                        layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
-                        HudLayer hud = layer.getHud();
-                        if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                            layer.changeFocusToPreviousSlot(1.0f);
-                        } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                            layer.changeFocusToNextSlot(1.0f);
-                        }
-                    } else {
-                        // in zoomed state
-                        // we do nothing for now, but we should clamp to the
-                        // image bounds
-                        boolean hitEdge = layer.constrainCameraForSlot(mCurrentSelectedSlot);
-                        // mPrevHitEdge = false;
-                        if (hitEdge && mPrevHitEdge) {
-                            float deltaX = posX - mFirstTouchPosX;
-                            float deltaY = posY - mFirstTouchPosY;
-                            maxPixelsBeforeSwitch *= 4;
-                            if (deltaY != 0) {
-                                // it has moved vertically
-                            }
-                            mPrevHitEdge = false;
-                            HudLayer hud = layer.getHud();
-                            if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                                layer.changeFocusToPreviousSlot(1.0f);
-                            } else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
-                                layer.changeFocusToNextSlot(1.0f);
-                            } else {
-                                mPrevHitEdge = hitEdge;
-                            }
-                        } else {
-                            mPrevHitEdge = hitEdge;
-                        }
-                    }
-                }
-            } else {
-                if (!layer.feedAboutToChange() && layer.getZoomValue() == 1.0f) {
-                    constrainCamera(true);
-                }
-            }
-        }
-        mCurrentFocusSlot = Shared.INVALID;
-        mCurrentFocusIsPressed = false;
-        mPrevTouchPosX = posX;
-        mPrevTouchPosY = posY;
-        mProcessTouch = false;
-    }
+	private void touchEnded(int posX, int posY, float timeElapsedx) {
+		if (mProcessTouch == false)
+			return;
+		int maxPixelsBeforeSwitch = mCamera.mWidth / 8;
+		mCamera.mConvergenceSpeed = 2.0f;
+		GridLayer layer = mLayer;
+		if (layer.getExpandedSlot() == Shared.INVALID && !layer.feedAboutToChange()) {
+			if (mCurrentSelectedSlot != Shared.INVALID) {
+				if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
+					if (!mTouchMoved) {
+						// tap gesture for fullscreen
+						if (layer.getZoomValue() == 1.0f)
+							layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
+					} else if (layer.getZoomValue() == 1.0f) {
+						// we want to snap to a new slotIndex based on where the
+						// current position is
+						if (layer.inSlideShowMode()) {
+							layer.endSlideshow();
+						}
+						float deltaX = posX - mFirstTouchPosX;
+						float deltaY = posY - mFirstTouchPosY;
+						if (deltaY != 0) {
+							// it has moved vertically
+						}
+						layer.changeFocusToSlot(mCurrentSelectedSlot, 1.0f);
+						HudLayer hud = layer.getHud();
+						if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+							layer.changeFocusToPreviousSlot(1.0f);
+						} else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+							layer.changeFocusToNextSlot(1.0f);
+						}
+					} else {
+						// in zoomed state
+						// we do nothing for now, but we should clamp to the
+						// image bounds
+						boolean hitEdge = layer.constrainCameraForSlot(mCurrentSelectedSlot);
+						// mPrevHitEdge = false;
+						if (hitEdge && mPrevHitEdge) {
+							float deltaX = posX - mFirstTouchPosX;
+							float deltaY = posY - mFirstTouchPosY;
+							maxPixelsBeforeSwitch *= 4;
+							if (deltaY != 0) {
+								// it has moved vertically
+							}
+							mPrevHitEdge = false;
+							HudLayer hud = layer.getHud();
+							if (deltaX > maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+								layer.changeFocusToPreviousSlot(1.0f);
+							} else if (deltaX < -maxPixelsBeforeSwitch && hud.getMode() != HudLayer.MODE_SELECT) {
+								layer.changeFocusToNextSlot(1.0f);
+							} else {
+								mPrevHitEdge = hitEdge;
+							}
+						} else {
+							mPrevHitEdge = hitEdge;
+						}
+					}
+				}
+			} else {
+				if (!layer.feedAboutToChange() && layer.getZoomValue() == 1.0f) {
+					constrainCamera(true);
+				}
+			}
+		}
+		mCurrentFocusSlot = Shared.INVALID;
+		mCurrentFocusIsPressed = false;
+		mPrevTouchPosX = posX;
+		mPrevTouchPosY = posY;
+		mProcessTouch = false;
+	}
 
-    private void constrainCamera(boolean b) {
-        Pool<Vector3f> pool = mPool;
-        GridLayer layer = mLayer;
-        Vector3f firstPosition = pool.create();
-        Vector3f lastPosition = pool.create();
-        Vector3f deltaAnchorPosition = pool.create();
-        try {
-            deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
-            GridCamera camera = mCamera;
-            LayoutInterface layout = layer.getLayoutInterface();
-            GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
-            int lastSlotIndex = 0;
-            IndexRange completeRange = layer.getCompleteRange();
-            synchronized (completeRange) {
-                lastSlotIndex = completeRange.end;
-            }
-            GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
-            camera.computeConstraints(true, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition);
-        } finally {
-            pool.delete(firstPosition);
-            pool.delete(lastPosition);
-            pool.delete(deltaAnchorPosition);
-        }
-    }
+	private void constrainCamera(boolean b) {
+		Pool<Vector3f> pool = mPool;
+		GridLayer layer = mLayer;
+		Vector3f firstPosition = pool.create();
+		Vector3f lastPosition = pool.create();
+		Vector3f deltaAnchorPosition = pool.create();
+		try {
+			deltaAnchorPosition.set(layer.getDeltaAnchorPosition());
+			GridCamera camera = mCamera;
+			LayoutInterface layout = layer.getLayoutInterface();
+			GridCameraManager.getSlotPositionForSlotIndex(0, camera, layout, deltaAnchorPosition, firstPosition);
+			int lastSlotIndex = 0;
+			IndexRange completeRange = layer.getCompleteRange();
+			synchronized (completeRange) {
+				lastSlotIndex = completeRange.end;
+			}
+			GridCameraManager.getSlotPositionForSlotIndex(lastSlotIndex, camera, layout, deltaAnchorPosition, lastPosition);
+			camera.computeConstraints(true, (layer.getState() != GridLayer.STATE_FULL_SCREEN), firstPosition, lastPosition);
+		} finally {
+			pool.delete(firstPosition);
+			pool.delete(lastPosition);
+			pool.delete(deltaAnchorPosition);
+		}
+	}
 
-    public void clearSelection() {
-        mCurrentSelectedSlot = Shared.INVALID;
-    }
+	public void clearSelection() {
+		mCurrentSelectedSlot = Shared.INVALID;
+	}
 
-    public void clearFocus() {
-        mCurrentFocusSlot = Shared.INVALID;
-    }
+	public void clearFocus() {
+		mCurrentFocusSlot = Shared.INVALID;
+	}
 
-    public boolean isFocusItemPressed() {
-        return mCurrentFocusIsPressed;
-    }
+	public boolean isFocusItemPressed() {
+		return mCurrentFocusIsPressed;
+	}
 
-    public void update(float timeElapsed) {
-        mDpadIgnoreTime += timeElapsed;
-    }
+	public void update(float timeElapsed) {
+		mDpadIgnoreTime += timeElapsed;
+	}
 
-    public void setCurrentFocusSlot(int slotId) {
-        mCurrentSelectedSlot = slotId;
-    }
+	public void setCurrentFocusSlot(int slotId) {
+		mCurrentSelectedSlot = slotId;
+	}
 
-    public boolean onDown(MotionEvent e) {
-        // TODO Auto-generated method stub
-        return true;
-    }
+	public boolean onDown(MotionEvent e) {
+		// TODO Auto-generated method stub
+		return true;
+	}
 
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-        if (mCurrentSelectedSlot == Shared.INVALID) {
-            mCamera.moveYTo(0);
-            mCamera.moveZTo(0);
-            mCamera.mConvergenceSpeed = 1.0f;
-            float normalizedVelocity = velocityX * mCamera.mOneByScale;
-            // mCamera.moveBy(-velocityX * mCamera.mOneByScale * 0.25f, 0, 0);
-            // constrainCamera(true);
-            IndexRange visibleRange = mLayer.getVisibleRange();
-            int numVisibleSlots = visibleRange.end - visibleRange.begin;
-            if (numVisibleSlots > 0) {
-                float fastFlingVelocity = 20.0f;
-                int slotsToSkip = (int) (numVisibleSlots * (-normalizedVelocity / fastFlingVelocity));
-                int maxSlots = numVisibleSlots;
-                if (slotsToSkip > maxSlots)
-                    slotsToSkip = maxSlots;
-                if (slotsToSkip < -maxSlots)
-                    slotsToSkip = -maxSlots;
-                if (Math.abs(slotsToSkip) <= 1) {
-                    if (velocityX > 0)
-                        slotsToSkip = -2;
-                    else if (velocityX < 0)
-                        slotsToSkip = 2;
-                }
-                int slotToGetTo = mLayer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER) + slotsToSkip;
-                if (slotToGetTo < 0)
-                    slotToGetTo = 0;
-                int lastSlot = mLayer.getCompleteRange().end;
-                if (slotToGetTo > lastSlot)
-                    slotToGetTo = lastSlot;
-                mLayer.centerCameraForSlot(slotToGetTo, 1.0f);
-            }
-            constrainCamera(true);
-            return true;
-        } else {
-            return false;
-        }
-    }
+	public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
+		if (mCurrentSelectedSlot == Shared.INVALID) {
+			mCamera.moveYTo(0);
+			mCamera.moveZTo(0);
+			mCamera.mConvergenceSpeed = 1.0f;
+			float normalizedVelocity = velocityX * mCamera.mOneByScale;
+			// mCamera.moveBy(-velocityX * mCamera.mOneByScale * 0.25f, 0, 0);
+			// constrainCamera(true);
+			IndexRange visibleRange = mLayer.getVisibleRange();
+			int numVisibleSlots = visibleRange.end - visibleRange.begin;
+			if (numVisibleSlots > 0) {
+				float fastFlingVelocity = 20.0f;
+				int slotsToSkip = (int) (numVisibleSlots * (-normalizedVelocity / fastFlingVelocity));
+				int maxSlots = numVisibleSlots;
+				if (slotsToSkip > maxSlots)
+					slotsToSkip = maxSlots;
+				if (slotsToSkip < -maxSlots)
+					slotsToSkip = -maxSlots;
+				if (Math.abs(slotsToSkip) <= 1) {
+					if (velocityX > 0)
+						slotsToSkip = -2;
+					else if (velocityX < 0)
+						slotsToSkip = 2;
+				}
+				int slotToGetTo = mLayer.getAnchorSlotIndex(GridLayer.ANCHOR_CENTER) + slotsToSkip;
+				if (slotToGetTo < 0)
+					slotToGetTo = 0;
+				int lastSlot = mLayer.getCompleteRange().end;
+				if (slotToGetTo > lastSlot)
+					slotToGetTo = lastSlot;
+				mLayer.centerCameraForSlot(slotToGetTo, 1.0f);
+			}
+			constrainCamera(true);
+			return true;
+		} else {
+			return false;
+		}
+	}
 
-    public void onLongPress(MotionEvent e) {
-        if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
-            HudLayer hud = mLayer.getHud();
-            hud.getPathBar().setHidden(true);
-            hud.getMenuBar().setHidden(true);
-            if (hud.getMode() != HudLayer.MODE_NORMAL)
-                hud.setMode(HudLayer.MODE_NORMAL);
-        }
-        if (mCurrentFocusSlot != Shared.INVALID) {
-            vibrateLong();
-            GridLayer layer = mLayer;
-            if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
-                layer.deselectAll();
-            }
-            HudLayer hud = layer.getHud();
-            hud.enterSelectionMode();
-            layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
-        }
-    }
+	public void onLongPress(MotionEvent e) {
+		if (mLayer.getFeed() != null && mLayer.getFeed().isSingleImageMode()) {
+			HudLayer hud = mLayer.getHud();
+			hud.getPathBar().setHidden(true);
+			hud.getMenuBar().setHidden(true);
+			if (hud.getMode() != HudLayer.MODE_NORMAL)
+				hud.setMode(HudLayer.MODE_NORMAL);
+		}
+		if (mCurrentFocusSlot != Shared.INVALID) {
+			vibrateLong();
+			GridLayer layer = mLayer;
+			if (layer.getState() == GridLayer.STATE_FULL_SCREEN) {
+				layer.deselectAll();
+			}
+			HudLayer hud = layer.getHud();
+			hud.enterSelectionMode();
+			layer.addSlotToSelectedItems(mCurrentFocusSlot, true, true);
+		}
+	}
 
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-        // TODO Auto-generated method stub
-        return false;
-    }
+	public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
+		// TODO Auto-generated method stub
+		return false;
+	}
 
-    public void onShowPress(MotionEvent e) {
-        // TODO Auto-generated method stub
+	public void onShowPress(MotionEvent e) {
+		// TODO Auto-generated method stub
 
-    }
+	}
 
-    public boolean onSingleTapUp(MotionEvent e) {
-        GridLayer layer = mLayer;
-        int posX = (int) e.getX();
-        int posY = (int) e.getY();
-        if (mCurrentSelectedSlot != Shared.INVALID) {
-            // Fullscreen mode.
-            mCamera.mConvergenceSpeed = 2.0f;
-            int slotId = mCurrentSelectedSlot;
-            if (layer.getZoomValue() == 1.0f) {
-                layer.centerCameraForSlot(slotId, 1.0f);
-            } else {
-                layer.constrainCameraForSlot(slotId);
-            }
-            DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
-            if (displayItem != null) {
-                final MediaItem item = displayItem.mItemRef;
-                int heightBy2 = mCamera.mHeight / 2;
-                boolean posYInBounds = (Math.abs(posY - heightBy2) < 64);
-                if (posX < 32 && posYInBounds) {
-                    layer.changeFocusToPreviousSlot(1.0f);
-                } else if (posX > mCamera.mWidth - 32 && posYInBounds) {
-                    layer.changeFocusToNextSlot(1.0f);
-                } else if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
-                    Utils.playVideo(mContext, item);
-                } else {
-                    // We stop any slideshow.
-                    HudLayer hud = layer.getHud();
-                    if (layer.inSlideShowMode()) {
-                        layer.endSlideshow();
-                    } else {
-                        hud.setAlpha(1.0f - hud.getAlpha());
-                    }
-                    if (hud.getMode() == HudLayer.MODE_SELECT) {
-                        hud.setAlpha(1.0f);
-                    }
-                }
-            }
-        } else {
-            int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
-            if (slotId != Shared.INVALID) {
-                HudLayer hud = layer.getHud();
-                if (hud.getMode() == HudLayer.MODE_SELECT) {
-                    layer.addSlotToSelectedItems(slotId, true, true);
-                } else {
-                    boolean centerCamera = (mCurrentSelectedSlot == Shared.INVALID) ? layer.tapGesture(slotId, false) : true;
-                    if (centerCamera) {
-                        // We check if this item is a video or not.
-                        selectSlot(slotId);
-                    }
-                }
-            } else {
-                int state = layer.getState();
-                if (state != GridLayer.STATE_FULL_SCREEN && state != GridLayer.STATE_GRID_VIEW
-                        && layer.getHud().getMode() != HudLayer.MODE_SELECT) {
-                    slotId = layer.getMetadataSlotIndexForScreenPosition(posX, posY);
-                    if (slotId != Shared.INVALID) {
-                        layer.tapGesture(slotId, true);
-                    }
-                }
-            }
-        }
-        return true;
-    }
+	public boolean onSingleTapUp(MotionEvent e) {
+		GridLayer layer = mLayer;
+		int posX = (int) e.getX();
+		int posY = (int) e.getY();
+		if (mCurrentSelectedSlot != Shared.INVALID) {
+			// Fullscreen mode.
+			mCamera.mConvergenceSpeed = 2.0f;
+			int slotId = mCurrentSelectedSlot;
+			if (layer.getZoomValue() == 1.0f) {
+				layer.centerCameraForSlot(slotId, 1.0f);
+			} else {
+				layer.constrainCameraForSlot(slotId);
+			}
+			DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
+			if (displayItem != null) {
+				final MediaItem item = displayItem.mItemRef;
+				int heightBy2 = mCamera.mHeight / 2;
+				boolean posYInBounds = (Math.abs(posY - heightBy2) < 64);
+				if (posX < 32 && posYInBounds) {
+					layer.changeFocusToPreviousSlot(1.0f);
+				} else if (posX > mCamera.mWidth - 32 && posYInBounds) {
+					layer.changeFocusToNextSlot(1.0f);
+				} else if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
+					Utils.playVideo(mContext, item);
+				} else {
+					// We stop any slideshow.
+					HudLayer hud = layer.getHud();
+					if (layer.inSlideShowMode()) {
+						layer.endSlideshow();
+					} else {
+						hud.setAlpha(1.0f - hud.getAlpha());
+					}
+					if (hud.getMode() == HudLayer.MODE_SELECT) {
+						hud.setAlpha(1.0f);
+					}
+				}
+			}
+		} else {
+			int slotId = layer.getSlotIndexForScreenPosition(posX, posY);
+			if (slotId != Shared.INVALID) {
+				HudLayer hud = layer.getHud();
+				if (hud.getMode() == HudLayer.MODE_SELECT) {
+					layer.addSlotToSelectedItems(slotId, true, true);
+				} else {
+					boolean centerCamera = (mCurrentSelectedSlot == Shared.INVALID) ? layer.tapGesture(slotId, false) : true;
+					if (centerCamera) {
+						// We check if this item is a video or not.
+						selectSlot(slotId);
+					}
+				}
+			} else {
+				int state = layer.getState();
+				if (state != GridLayer.STATE_FULL_SCREEN && state != GridLayer.STATE_GRID_VIEW
+				        && layer.getHud().getMode() != HudLayer.MODE_SELECT) {
+					slotId = layer.getMetadataSlotIndexForScreenPosition(posX, posY);
+					if (slotId != Shared.INVALID) {
+						layer.tapGesture(slotId, true);
+					}
+				}
+			}
+		}
+		return true;
+	}
 
-    private void selectSlot(int slotId) {
-        GridLayer layer = mLayer;
-        if (layer.getState() == GridLayer.STATE_GRID_VIEW) {
-            DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
-            if (displayItem != null) {
-                final MediaItem item = displayItem.mItemRef;
-                if (layer.getPickIntent()) {
-                    // we need to return this item
-                    ((Gallery) mContext).getHandler().post(new Runnable() {
-                        public void run() {
-                            ((Gallery) mContext).launchCropperOrFinish(item);
-                        }
-                    });
-                    return;
-                }
-                if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
-                    Utils.playVideo(mContext, item);
-                } else {
-                    mCurrentSelectedSlot = slotId;
-                    layer.endSlideshow();
-                    layer.setState(GridLayer.STATE_FULL_SCREEN);
-                    mCamera.mConvergenceSpeed = 2.0f;
-                    layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
-                }
-            }
-        }
-    }
+	private void selectSlot(int slotId) {
+		GridLayer layer = mLayer;
+		if (layer.getState() == GridLayer.STATE_GRID_VIEW) {
+			DisplayItem displayItem = layer.getDisplayItemForSlotId(slotId);
+			if (displayItem != null) {
+				final MediaItem item = displayItem.mItemRef;
+				if (layer.getPickIntent()) {
+					// we need to return this item
+					((Gallery) mContext).getHandler().post(new Runnable() {
+						public void run() {
+							((Gallery) mContext).launchCropperOrFinish(item);
+						}
+					});
+					return;
+				}
+				if (item.getMediaType() == MediaItem.MEDIA_TYPE_VIDEO) {
+					Utils.playVideo(mContext, item);
+				} else {
+					mCurrentSelectedSlot = slotId;
+					layer.endSlideshow();
+					layer.setState(GridLayer.STATE_FULL_SCREEN);
+					mCamera.mConvergenceSpeed = 2.0f;
+					layer.getHud().fullscreenSelectionChanged(item, mCurrentSelectedSlot + 1, layer.getCompleteRange().end + 1);
+				}
+			}
+		}
+	}
 
-    public boolean onDoubleTap(MotionEvent e) {
-        final GridLayer layer = mLayer;
-        if (layer.getState() == GridLayer.STATE_FULL_SCREEN && !mCamera.isZAnimating()) {
-            float posX = e.getX();
-            float posY = e.getY();
-            final Vector3f retVal = new Vector3f();
-            posX -= (mCamera.mWidth / 2);
-            posY -= (mCamera.mHeight / 2);
-            mCamera.convertToRelativeCameraSpace(posX, posY, 0, retVal);
-            if (layer.getZoomValue() == 1.0f) {
-                layer.setZoomValue(3f);
-                mCamera.update(0.001f);
-                mCamera.moveBy(retVal.x, retVal.y, 0);
-                layer.constrainCameraForSlot(mCurrentSelectedSlot);
-            } else {
-                layer.setZoomValue(1.0f);
-            }
-            mCamera.mConvergenceSpeed = 2.0f;
-        } else {
-            return onSingleTapConfirmed(e);
-        }
-        return true;
-    }
+	public boolean onDoubleTap(MotionEvent e) {
+		final GridLayer layer = mLayer;
+		if (layer.getState() == GridLayer.STATE_FULL_SCREEN && !mCamera.isZAnimating()) {
+			float posX = e.getX();
+			float posY = e.getY();
+			final Vector3f retVal = new Vector3f();
+			posX -= (mCamera.mWidth / 2);
+			posY -= (mCamera.mHeight / 2);
+			mCamera.convertToRelativeCameraSpace(posX, posY, 0, retVal);
+			if (layer.getZoomValue() == 1.0f) {
+				layer.setZoomValue(3f);
+				mCamera.update(0.001f);
+				mCamera.moveBy(retVal.x, retVal.y, 0);
+				layer.constrainCameraForSlot(mCurrentSelectedSlot);
+			} else {
+				layer.setZoomValue(1.0f);
+			}
+			mCamera.mConvergenceSpeed = 2.0f;
+		} else {
+			return onSingleTapConfirmed(e);
+		}
+		return true;
+	}
 
-    public boolean onDoubleTapEvent(MotionEvent e) {
-        return false;
-    }
+	public boolean onDoubleTapEvent(MotionEvent e) {
+		return false;
+	}
 
-    public boolean onSingleTapConfirmed(MotionEvent e) {
-        return false;
-    }
+	public boolean onSingleTapConfirmed(MotionEvent e) {
+		return false;
+	}
 
-    public boolean touchPressed() {
-        return mProcessTouch;
-    }
+	public boolean touchPressed() {
+		return mProcessTouch;
+	}
 
-    private void vibrateShort() {
-        // As per request by Google, this line disables vibration.
-        //mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
-    }
+	private void vibrateShort() {
+		// As per request by Google, this line disables vibration.
+		// mView.performHapticFeedback(HapticFeedbackConstants.LONG_PRESS);
+	}
 
-    private void vibrateLong() {
-        //mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
-    }
+	private void vibrateLong() {
+		// mView.performHapticFeedback(HapticFeedbackConstants.VIRTUAL_KEY);
+	}
 }
diff --git a/src/com/cooliris/media/GridLayer.java b/src/com/cooliris/media/GridLayer.java
index 61bea47..2693752 100644
--- a/src/com/cooliris/media/GridLayer.java
+++ b/src/com/cooliris/media/GridLayer.java
@@ -59,14 +59,14 @@
 	private static Vector3f sDeltaAnchorPosition = new Vector3f();
 
 	// The display primitives.
-	private GridDrawables mDrawables;
+	final private GridDrawables mDrawables;
 	private float mSelectedAlpha = 0.0f;
 	private float mTargetAlpha = 0.0f;
 
-	private GridCamera mCamera;
-	private GridCameraManager mCameraManager;
-	private GridDrawManager mDrawManager;
-	private GridInputProcessor mInputProcessor;
+	final private GridCamera mCamera;
+	final private GridCameraManager mCameraManager;
+	final private GridDrawManager mDrawManager;
+	final private GridInputProcessor mInputProcessor;
 
 	private boolean mFeedAboutToChange;
 	private boolean mPerformingLayoutChange;
@@ -85,7 +85,7 @@
 	private static ArrayList<MediaItem> sVisibleItems;
 
 	private float mTimeElapsedSinceTransition;
-	private BackgroundLayer mBackground;
+	private final BackgroundLayer mBackground;
 	private boolean mLocationFilter;
 	private float mZoomValue = 1.0f;
 	private float mCurrentFocusItemWidth = 1.0f;
@@ -107,13 +107,11 @@
 	private int mFramesDirty;
 	private String mRequestFocusContentUri;
 	private int mFrameCount;
-	private boolean mNeedsInit;
 
 	public GridLayer(Context context, int itemWidth, int itemHeight, LayoutInterface layoutInterface, RenderView view) {
 		mBackground = new BackgroundLayer(this);
 		mContext = context;
 		mView = view;
-		mNeedsInit = true;
 
 		DisplaySlot[] displaySlots = sDisplaySlots;
 		for (int i = 0; i < MAX_DISPLAY_SLOTS; ++i) {
@@ -165,7 +163,6 @@
 			mMediaFeed.shutdown();
 		}
 		mContext = null;
-		mBackground = null;
 		sBucketList.clear();
 		mView = null;
 	}
diff --git a/src/com/cooliris/media/LocalDataSource.java b/src/com/cooliris/media/LocalDataSource.java
index 1ff37a3..f93d559 100644
--- a/src/com/cooliris/media/LocalDataSource.java
+++ b/src/com/cooliris/media/LocalDataSource.java
@@ -111,7 +111,6 @@
         if (setIdToUse == Shared.INVALID) {
             return;
         }
-        Log.i(TAG, "Refreshing local data source");
         if (feed.getMediaSet(setIdToUse) == null) {
             MediaSet mediaSet = feed.addMediaSet(setIdToUse, this);
             if (setIdToUse == CAMERA_BUCKET_ID) {
@@ -122,6 +121,7 @@
             mediaSet.generateTitle(true);
         } else {
             MediaSet mediaSet = feed.replaceMediaSet(setIdToUse, this);
+            Log.i(TAG, "Replacing mediaset " + mediaSet.mName + " id " + setIdToUse + " current Id " + mediaSet.mId);
             if (setIdToUse == CAMERA_BUCKET_ID) {
                 mediaSet.mName = CAMERA_STRING;
             } else if (setIdToUse == DOWNLOAD_BUCKET_ID) {
diff --git a/src/com/cooliris/media/MediaFeed.java b/src/com/cooliris/media/MediaFeed.java
index a72a9c6..f905ed0 100644
--- a/src/com/cooliris/media/MediaFeed.java
+++ b/src/com/cooliris/media/MediaFeed.java
@@ -704,9 +704,11 @@
         ArrayList<MediaSet> mediaSets = mMediaSets;
         int numSets = mediaSets.size();
         for (int i = 0; i < numSets; ++i) {
-            if (mediaSets.get(i).mId == setId) {
-                MediaSet thisSet = mediaSets.get(i);
+        	final MediaSet thisSet = mediaSets.get(i);
+            if (thisSet.mId == setId) {
                 mediaSet.mName = thisSet.mName;
+                mediaSet.mHasImages = thisSet.mHasImages;
+                mediaSet.mHasVideos = thisSet.mHasVideos;
                 mediaSets.set(i, mediaSet);
                 break;
             }
diff --git a/src/com/cooliris/media/PicasaDataSource.java b/src/com/cooliris/media/PicasaDataSource.java
index e3b9f87..868a23e 100644
--- a/src/com/cooliris/media/PicasaDataSource.java
+++ b/src/com/cooliris/media/PicasaDataSource.java
@@ -42,7 +42,7 @@
         for (int i = 0; i < numAccounts; ++i) {
             Account account = accounts[i];
             boolean isEnabled = ContentResolver.getSyncAutomatically(account, PicasaContentProvider.AUTHORITY);
-            String username = account.name;
+            String username = account.name.toLowerCase();
             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('@'));
@@ -109,7 +109,8 @@
                 final ArrayList<MediaSet> picasaSets = new ArrayList<MediaSet>(numAlbums);
                 do {
                     albumSchema.cursorToObject(cursor, album);
-                    final Boolean accountEnabledObj = accountsEnabled.get(album.user);
+                    String userLowerCase = album.user.toLowerCase();
+                    final Boolean accountEnabledObj = accountsEnabled.get(userLowerCase);
                     final boolean accountEnabled = (accountEnabledObj == null) ? false : accountEnabledObj.booleanValue();
                     if (accountEnabled) {
                         mediaSet = feed.getMediaSet(album.id);