diff --git a/src/com/android/camera/ImageGallery2.java b/src/com/android/camera/ImageGallery2.java
index b9518b9..27890e3 100644
--- a/src/com/android/camera/ImageGallery2.java
+++ b/src/com/android/camera/ImageGallery2.java
@@ -16,17 +16,22 @@
 
 package com.android.camera;
 
-import android.content.BroadcastReceiver;
+import com.android.camera.gallery.IImage;
+import com.android.camera.gallery.IImageList;
+import com.android.camera.gallery.VideoObject;
+
 import android.app.Activity;
-import android.app.Dialog;
 import android.app.AlertDialog;
+import android.app.Dialog;
 import android.app.ProgressDialog;
+import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.content.SharedPreferences;
 import android.content.pm.ActivityInfo;
+import android.content.res.Configuration;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
@@ -38,6 +43,8 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.PowerManager;
+import android.preference.PreferenceManager;
+import android.provider.MediaStore;
 import android.util.AttributeSet;
 import android.util.Config;
 import android.util.Log;
@@ -51,27 +58,21 @@
 import android.view.View;
 import android.view.ViewConfiguration;
 import android.view.Window;
+import android.widget.Scroller;
 import android.widget.TextView;
 import android.widget.Toast;
-import android.preference.PreferenceManager;
-import android.provider.MediaStore;
-import android.widget.Scroller;
 
 import java.util.Calendar;
 import java.util.GregorianCalendar;
 
-import com.android.camera.gallery.IImage;
-import com.android.camera.gallery.IImageList;
-import com.android.camera.gallery.VideoObject;
-
 public class ImageGallery2 extends Activity {
     private static final String TAG = "ImageGallery2";
-    private IImageList mAllImages;
+    IImageList mAllImages;
     private int mInclusion;
-    private boolean mSortAscending = false;
+    boolean mSortAscending = false;
     private View mNoImagesView;
-    public final static int CROP_MSG = 2;
-    public final static int VIEW_MSG = 3;
+    public static final int CROP_MSG = 2;
+    public static final int VIEW_MSG = 3;
     private static final String INSTANCE_STATE_TAG = "scrollY";
 
     private Dialog mMediaScanningDialog;
@@ -100,12 +101,16 @@
 
         mPrefs = PreferenceManager.getDefaultSharedPreferences(this);
 
-        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);  // must be called before setContentView()
+        // Must be called before setContentView().
+        requestWindowFeature(Window.FEATURE_CUSTOM_TITLE);
+
         setContentView(R.layout.image_gallery_2);
 
-        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE, R.layout.custom_gallery_title);
-        if (Config.LOGV)
+        getWindow().setFeatureInt(Window.FEATURE_CUSTOM_TITLE,
+                R.layout.custom_gallery_title);
+        if (Config.LOGV) {
             Log.v(TAG, "findView... " + findViewById(R.id.loading_indicator));
+        }
 
         mGvs = (GridViewSpecial) findViewById(R.id.grid);
         mGvs.requestFocus();
@@ -117,82 +122,45 @@
         } else {
             mVideoSizeLimit = Long.MAX_VALUE;
             mGvs.mVideoSizeLimit = mVideoSizeLimit;
-            mGvs.setOnCreateContextMenuListener(new View.OnCreateContextMenuListener() {
-                public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
-                    if (mSelectedImageGetter.getCurrentImage() == null)
-                        return;
-
-                    boolean isImage = ImageManager.isImage(mSelectedImageGetter.getCurrentImage());
-                    if (isImage) {
-                        menu.add(0, 0, 0, R.string.view).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                            public boolean onMenuItemClick(MenuItem item) {
-                                mGvs.onSelect(mGvs.mCurrentSelection);
-                                return true;
-                            }
-                        });
-                    }
-
-                    menu.setHeaderTitle(isImage ? R.string.context_menu_header
-                            : R.string.video_context_menu_header);
-                    if ((mInclusion & (ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS)) != 0) {
-                        MenuHelper.MenuItemsResult r = MenuHelper.addImageMenuItems(
-                                menu,
-                                MenuHelper.INCLUDE_ALL,
-                                isImage,
-                                ImageGallery2.this,
-                                mHandler,
-                                mDeletePhotoRunnable,
-                                new MenuHelper.MenuInvoker() {
-                                    public void run(MenuHelper.MenuCallback cb) {
-                                        cb.run(mSelectedImageGetter.getCurrentImageUri(), mSelectedImageGetter.getCurrentImage());
-
-                                        mGvs.clearCache();
-                                        mGvs.invalidate();
-                                        mGvs.requestLayout();
-                                        mGvs.start();
-                                        mNoImagesView.setVisibility(mAllImages.getCount() > 0 ? View.GONE : View.VISIBLE);
-                                    }
-                                });
-                        if (r != null)
-                            r.gettingReadyToOpen(menu, mSelectedImageGetter.getCurrentImage());
-
-                        if (isImage) {
-                            addSlideShowMenu(menu, 1000);
-                        }
-                    }
-                }
-            });
+            mGvs.setOnCreateContextMenuListener(
+                    new CreateContextMenuListener());
         }
     }
 
     private MenuItem addSlideShowMenu(Menu menu, int position) {
         return menu.add(0, 207, position, R.string.slide_show)
-        .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-            public boolean onMenuItemClick(MenuItem item) {
-                IImage img = mSelectedImageGetter.getCurrentImage();
-                if (img == null) {
-                    img = mAllImages.getImageAt(0);
-                    if (img == null) {
-                        return true;
+                .setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
+                    public boolean onMenuItemClick(MenuItem item) {
+                        return onSlideShowClicked();
                     }
-                }
-                Uri targetUri = img.fullSizeImageUri();
-                Uri thisUri = getIntent().getData();
-                if (thisUri != null) {
-                    String bucket = thisUri.getQueryParameter("bucketId");
-                    if (bucket != null) {
-                        targetUri = targetUri.buildUpon().appendQueryParameter("bucketId", bucket).build();
-                    }
-                }
-                Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
-                intent.putExtra("slideshow", true);
-                startActivity(intent);
-                return true;
-            }
-        })
-        .setIcon(android.R.drawable.ic_menu_slideshow);
+                }).setIcon(android.R.drawable.ic_menu_slideshow);
     }
 
+    public boolean onSlideShowClicked() {
+        IImage img = mSelectedImageGetter.getCurrentImage();
+        if (img == null) {
+            img = mAllImages.getImageAt(0);
+            if (img == null) {
+                return true;
+            }
+        }
+        Uri targetUri = img.fullSizeImageUri();
+        Uri thisUri = getIntent().getData();
+        if (thisUri != null) {
+            String bucket = thisUri.getQueryParameter("bucketId");
+            if (bucket != null) {
+                targetUri = targetUri.buildUpon()
+                        .appendQueryParameter("bucketId", bucket)
+                        .build();
+            }
+        }
+        Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
+        intent.putExtra("slideshow", true);
+        startActivity(intent);
+        return true;
+    }
+    
     private Runnable mDeletePhotoRunnable = new Runnable() {
         public void run() {
             mGvs.clearCache();
@@ -203,29 +171,35 @@
             mGvs.invalidate();
             mGvs.requestLayout();
             mGvs.start();
-            mNoImagesView.setVisibility(mAllImages.isEmpty() ? View.VISIBLE : View.GONE);
+            mNoImagesView.setVisibility(mAllImages.isEmpty()
+                    ? View.VISIBLE
+                    : View.GONE);
         }
     };
 
-    private SelectedImageGetter mSelectedImageGetter = new SelectedImageGetter() {
-        public Uri getCurrentImageUri() {
-            IImage image = getCurrentImage();
-            if (image != null)
-                return image.fullSizeImageUri();
-            else
-                return null;
-        }
-        public IImage getCurrentImage() {
-            int currentSelection = mGvs.mCurrentSelection;
-            if (currentSelection < 0 || currentSelection >= mAllImages.getCount())
-                return null;
-            else
-                return mAllImages.getImageAt(currentSelection);
-        }
-    };
+    private SelectedImageGetter mSelectedImageGetter =
+            new SelectedImageGetter() {
+                public Uri getCurrentImageUri() {
+                    IImage image = getCurrentImage();
+                    if (image != null) {
+                        return image.fullSizeImageUri();
+                    } else {
+                        return null;
+                    }
+                }
+                public IImage getCurrentImage() {
+                    int currentSelection = mGvs.mCurrentSelection;
+                    if (currentSelection < 0
+                            || currentSelection >= mAllImages.getCount()) {
+                        return null;
+                    } else {
+                        return mAllImages.getImageAt(currentSelection);
+                    }
+                }
+            };
 
     @Override
-    public void onConfigurationChanged(android.content.res.Configuration newConfig) {
+    public void onConfigurationChanged(Configuration newConfig) {
         super.onConfigurationChanged(newConfig);
         mTargetScroll = mGvs.getScrollY();
     }
@@ -237,19 +211,21 @@
         }
     };
 
-    private boolean canHandleEvent() {
+    boolean canHandleEvent() {
         // Don't process event in pause state.
         return (!mPausing) && (mGvs.mCurrentSpec != null);
     }
     
     @Override
     public boolean onKeyUp(int keyCode, KeyEvent event) {
-        if (!canHandleEvent())  return false;
+        if (!canHandleEvent()) return false;
         
         if (keyCode == KeyEvent.KEYCODE_DPAD_CENTER) {
             mGvs.select(-2, false);
-            // The keyUp doesn't get called when the longpress menu comes up. We only get here when the user
-            // lets go of the center key before the longpress menu comes up.
+            
+            // The keyUp doesn't get called when the longpress menu comes up. We
+            // only get here when the user lets go of the center key before the
+            // longpress menu comes up.
             mHandler.removeCallbacks(mLongPressCallback);
 
             // open the photo
@@ -263,7 +239,7 @@
     
     @Override
     public boolean onKeyDown(int keyCode, KeyEvent event) {
-        if (!canHandleEvent())  return false;
+        if (!canHandleEvent()) return false;
         
         boolean handled = true;
         int sel = mGvs.mCurrentSelection;
@@ -288,13 +264,14 @@
                     }
                     break;
                 case KeyEvent.KEYCODE_DPAD_DOWN:
-                    if ((sel / columns) != (sel+columns / columns)) {
-                        sel = Math.min(count-1, sel + columns);
+                    if ((sel / columns) != (sel + columns / columns)) {
+                        sel = Math.min(count - 1, sel + columns);
                     }
                     break;
                 case KeyEvent.KEYCODE_DPAD_CENTER:
                     pressed = true;
-                    mHandler.postDelayed(mLongPressCallback, ViewConfiguration.getLongPressTimeout());
+                    mHandler.postDelayed(mLongPressCallback,
+                            ViewConfiguration.getLongPressTimeout());
                     break;
                 case KeyEvent.KEYCODE_DEL:
                     MenuHelper.deleteImage(this, mDeletePhotoRunnable,
@@ -306,41 +283,45 @@
             }
         } else {
             switch (keyCode) {
-            case KeyEvent.KEYCODE_DPAD_RIGHT:
-            case KeyEvent.KEYCODE_DPAD_LEFT:
-            case KeyEvent.KEYCODE_DPAD_UP:
-            case KeyEvent.KEYCODE_DPAD_DOWN:
-                int [] range = new int[2];
-                GridViewSpecial.ImageBlockManager ibm = mGvs.mImageBlockManager;
-                if (ibm != null) {
-                    mGvs.mImageBlockManager.getVisibleRange(range);
-                    int topPos = range[0];
-                    android.graphics.Rect r = mGvs.getRectForPosition(topPos);
-                    if (r.top < mGvs.getScrollY())
-                        topPos += columns;
-                    topPos = Math.min(count - 1, topPos);
-                    sel = topPos;
-                }
-                break;
-            default:
-                handled = false;
-                break;
+                case KeyEvent.KEYCODE_DPAD_RIGHT:
+                case KeyEvent.KEYCODE_DPAD_LEFT:
+                case KeyEvent.KEYCODE_DPAD_UP:
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    int [] range = new int[2];
+                    GridViewSpecial.ImageBlockManager ibm =
+                            mGvs.mImageBlockManager;
+                    if (ibm != null) {
+                        mGvs.mImageBlockManager.getVisibleRange(range);
+                        int topPos = range[0];
+                        android.graphics.Rect r =
+                                mGvs.getRectForPosition(topPos);
+                        if (r.top < mGvs.getScrollY()) {
+                            topPos += columns;
+                        }
+                        topPos = Math.min(count - 1, topPos);
+                        sel = topPos;
+                    }
+                    break;
+                default:
+                    handled = false;
+                    break;
             }
         }
         if (handled) {
             mGvs.select(sel, pressed);
             return true;
-        }
-        else
+        } else {
             return super.onKeyDown(keyCode, event);
+        }
     }
 
-    private boolean isPickIntent() {
+    boolean isPickIntent() {
         String action = getIntent().getAction();
-        return (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action));
+        return (Intent.ACTION_PICK.equals(action)
+                || Intent.ACTION_GET_CONTENT.equals(action));
     }
 
-    private void launchCropperOrFinish(IImage img) {
+    void launchCropperOrFinish(IImage img) {
         Bundle myExtras = getIntent().getExtras();
 
         long size = MenuHelper.getImageFileSize(img);
@@ -369,8 +350,9 @@
         String cropValue = myExtras != null ? myExtras.getString("crop") : null;
         if (cropValue != null) {
             Bundle newExtras = new Bundle();
-            if (cropValue.equals("circle"))
+            if (cropValue.equals("circle")) {
                 newExtras.putString("circleCrop", "true");
+            }
 
             Intent cropIntent = new Intent();
             cropIntent.setData(img.fullSizeImageUri());
@@ -385,8 +367,9 @@
             Intent result = new Intent(null, img.fullSizeImageUri());
             if (myExtras != null && myExtras.getString("return-data") != null) {
                 Bitmap bitmap = img.fullSizeBitmap(1000);
-                if (bitmap != null)
+                if (bitmap != null) {
                     result.putExtra("data", bitmap);
+                }
             }
             setResult(RESULT_OK, result);
             finish();
@@ -394,18 +377,22 @@
     }
 
     @Override
-    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (Config.LOGV)
-            Log.v(TAG, "onActivityResult: " + requestCode + "; resultCode is " + resultCode + "; data is " + data);
+    protected void onActivityResult(int requestCode, int resultCode,
+            Intent data) {
+        if (Config.LOGV) {
+            Log.v(TAG, "onActivityResult: " + requestCode
+                    + "; resultCode is " + resultCode + "; data is " + data);
+        }
         switch (requestCode) {
             case MenuHelper.RESULT_COMMON_MENU_CROP: {
                 if (resultCode == RESULT_OK) {
-                    // The CropImage activity passes back the Uri of the cropped image as
-                    // the Action rather than the Data.
+
+                    // The CropImage activity passes back the Uri of the cropped
+                    // image as the Action rather than the Data.
                     Uri dataUri = Uri.parse(data.getAction());
-                    rebake(false,false);
+                    rebake(false, false);
                     IImage image = mAllImages.getImageForUri(dataUri);
-                    if (image != null ) {
+                    if (image != null) {
                         int rowId = image.getRow();
                         mGvs.select(rowId, false);
                     }
@@ -421,8 +408,9 @@
                 break;
             }
             case VIEW_MSG: {
-                if (Config.LOGV)
+                if (Config.LOGV) {
                     Log.v(TAG, "got VIEW_MSG with " + data);
+                }
                 IImage img = mAllImages.getImageForUri(data.getData());
                 launchCropperOrFinish(img);
                 break;
@@ -441,8 +429,9 @@
             unregisterReceiver(mReceiver);
             mReceiver = null;
         }
-        // Now that we've paused the threads that are using the cursor it is safe
-        // to deactivate it.
+
+        // Now that we've paused the threads that are using the cursor it is
+        // safe to deactivate it.
         mAllImages.deactivate();
     }
 
@@ -467,8 +456,9 @@
             mAllImages = ImageManager.instance().emptyImageList();
         } else {
             mAllImages = allImages(!unmounted);
-            if (Config.LOGV)
+            if (Config.LOGV) {
                 Log.v(TAG, "mAllImages is now " + mAllImages);
+            }
             mGvs.init(mHandler);
             mGvs.start();
             mGvs.requestLayout();
@@ -496,19 +486,21 @@
         super.onResume();
 
         try {
-            mGvs.setSizeChoice(Integer.parseInt(mPrefs.getString("pref_gallery_size_key", "1")), mTargetScroll);
+            mGvs.setSizeChoice(Integer.parseInt(
+                    mPrefs.getString("pref_gallery_size_key", "1")),
+                    mTargetScroll);
 
             String sortOrder = mPrefs.getString("pref_gallery_sort_key", null);
             if (sortOrder != null) {
                 mSortAscending = sortOrder.equals("ascending");
             }
-        } catch (Exception ex) {
-
+        } catch (RuntimeException ex) {
         }
         mPausing = false;
 
         // install an intent filter to receive SD card related events.
-        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
+        IntentFilter intentFilter =
+                new IntentFilter(Intent.ACTION_MEDIA_MOUNTED);
         intentFilter.addAction(Intent.ACTION_MEDIA_UNMOUNTED);
         intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_STARTED);
         intentFilter.addAction(Intent.ACTION_MEDIA_SCANNER_FINISHED);
@@ -518,7 +510,9 @@
         mReceiver = new BroadcastReceiver() {
             @Override
             public void onReceive(Context context, Intent intent) {
-                if (Config.LOGV) Log.v(TAG, "onReceiveIntent " + intent.getAction());
+                if (Config.LOGV) {
+                    Log.v(TAG, "onReceiveIntent " + intent.getAction());
+                }
                 String action = intent.getAction();
                 if (action.equals(Intent.ACTION_MEDIA_MOUNTED)) {
                     // SD card available
@@ -527,18 +521,24 @@
                 } else if (action.equals(Intent.ACTION_MEDIA_UNMOUNTED)) {
                     // SD card unavailable
                     if (Config.LOGV) Log.v(TAG, "sd card no longer available");
-                    Toast.makeText(ImageGallery2.this, getResources().getString(R.string.wait), 5000);
+                    Toast.makeText(ImageGallery2.this,
+                            getResources().getString(R.string.wait), 5000);
                     rebake(true, false);
                 } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_STARTED)) {
-                    Toast.makeText(ImageGallery2.this, getResources().getString(R.string.wait), 5000);
+                    Toast.makeText(ImageGallery2.this,
+                            getResources().getString(R.string.wait), 5000);
                     rebake(false, true);
-                } else if (action.equals(Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
-                    if (Config.LOGV)
-                        Log.v(TAG, "rebake because of ACTION_MEDIA_SCANNER_FINISHED");
+                } else if (action.equals(
+                        Intent.ACTION_MEDIA_SCANNER_FINISHED)) {
+                    if (Config.LOGV) {
+                        Log.v(TAG, "rebake because of "
+                                + "ACTION_MEDIA_SCANNER_FINISHED");
+                    }
                     rebake(false, false);
                 } else if (action.equals(Intent.ACTION_MEDIA_EJECT)) {
-                    if (Config.LOGV)
+                    if (Config.LOGV) {
                         Log.v(TAG, "rebake because of ACTION_MEDIA_EJECT");
+                    }
                     rebake(true, false);
                 }
             }
@@ -564,60 +564,74 @@
         mThumbnailCheckThread = new CameraThread(new Runnable() {
             public void run() {
                 android.content.res.Resources resources = getResources();
-                final TextView progressTextView = (TextView) findViewById(R.id.loading_text);
-                final String progressTextFormatString = resources.getString(R.string.loading_progress_format_string);
+                final TextView progressTextView =
+                        (TextView) findViewById(R.id.loading_text);
+                final String progressTextFormatString =
+                        resources.getString(
+                        R.string.loading_progress_format_string);
 
-                PowerManager pm = (PowerManager)getSystemService(Context.POWER_SERVICE);
+                PowerManager pm =
+                        (PowerManager) getSystemService(Context.POWER_SERVICE);
                 PowerManager.WakeLock mWakeLock =
                     pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK,
                                    "ImageGallery2.checkThumbnails");
                 mWakeLock.acquire();
-                IImageList.ThumbCheckCallback r = new IImageList.ThumbCheckCallback() {
-                    boolean mDidSetProgress = false;
+                IImageList.ThumbCheckCallback r =
+                        new IImageList.ThumbCheckCallback() {
+                            boolean mDidSetProgress = false;
 
-                    public boolean checking(final int count, final int maxCount) {
-                        if (mStopThumbnailChecking) {
-                            return false;
-                        }
-
-                        if (!mLayoutComplete) {
-                            return true;
-                        }
-
-                        if (!mDidSetProgress) {
-                            mHandler.post(new Runnable() {
-                                public void run() {
-                                    findViewById(R.id.loading_indicator).setVisibility(View.VISIBLE);
+                            public boolean checking(final int count,
+                                    final int maxCount) {
+                                if (mStopThumbnailChecking) {
+                                    return false;
                                 }
-                            });
-                            mDidSetProgress = true;
-                        }
-                        mGvs.postInvalidate();
 
-                        if (System.currentTimeMillis() - startTime > 1000) {
-                            mHandler.post(new Runnable() {
-                                public void run() {
-                                    String s = String.format(progressTextFormatString, maxCount - count);
-                                    progressTextView.setText(s);
+                                if (!mLayoutComplete) {
+                                    return true;
                                 }
-                            });
-                        }
 
-                        return !mPausing;
-                    }
-                };
+                                if (!mDidSetProgress) {
+                                    mHandler.post(new Runnable() {
+                                        public void run() {
+                                                findViewById(
+                                                R.id.loading_indicator)
+                                                .setVisibility(View.VISIBLE);
+                                        }
+                                    });
+                                    mDidSetProgress = true;
+                                }
+                                mGvs.postInvalidate();
+
+                                if (System.currentTimeMillis()
+                                        - startTime > 1000) {
+                                    mHandler.post(new Runnable() {
+                                        public void run() {
+                                            String s = String.format(
+                                                    progressTextFormatString,
+                                                    maxCount - count);
+                                            progressTextView.setText(s);
+                                        }
+                                    });
+                                }
+
+                                return !mPausing;
+                            }
+                        };
                 IImageList imageList = allImages(true);
                 imageList.checkThumbnails(r, imageList.getCount());
                 mWakeLock.release();
                 mThumbnailCheckThread = null;
                 mHandler.post(new Runnable() {
                     public void run() {
-                        findViewById(R.id.loading_indicator).setVisibility(View.GONE);
+                        findViewById(R.id.loading_indicator).setVisibility(
+                                View.GONE);
                     }
                 });
                 long t2 = System.currentTimeMillis();
-                if (Config.LOGV)
-                    Log.v(TAG, "check thumbnails thread finishing; took " + (t2-t1));
+                if (Config.LOGV) {
+                    Log.v(TAG, "check thumbnails thread finishing; took "
+                            + (t2 - t1));
+                }
             }
         });
 
@@ -626,7 +640,9 @@
         mThumbnailCheckThread.toBackground();
 
         IImageList list = allImages(true);
-        mNoImagesView.setVisibility(list.getCount() > 0 ? View.GONE : View.VISIBLE);
+        mNoImagesView.setVisibility(list.getCount() > 0
+                ? View.GONE
+                : View.VISIBLE);
     }
 
     @Override
@@ -660,7 +676,8 @@
     public boolean onPrepareOptionsMenu(android.view.Menu menu) {
         if ((mInclusion & ImageManager.INCLUDE_IMAGES) != 0) {
             boolean videoSelected = isVideoSelected();
-            // TODO: Only enable slide show if there is at least one image in the folder.
+            // TODO: Only enable slide show if there is at least one image in
+            // the folder.
             if (mSlideShowItem != null) {
                 mSlideShowItem.setEnabled(!videoSelected);
             }
@@ -683,39 +700,50 @@
         if (mAllImages == null) {
             mNoImagesView = findViewById(R.id.no_images);
 
-            mInclusion = ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS;
+            mInclusion = ImageManager.INCLUDE_IMAGES
+                    | ImageManager.INCLUDE_VIDEOS;
 
             Intent intent = getIntent();
             if (intent != null) {
                 String type = intent.resolveType(this);
-                if (Config.LOGV)
+                if (Config.LOGV) {
                     Log.v(TAG, "allImages... type is " + type);
+                }
                 TextView leftText = (TextView) findViewById(R.id.left_text);
                 if (type != null) {
-                    if (type.equals("vnd.android.cursor.dir/image") || type.equals("image/*")) {
+                    if (type.equals("vnd.android.cursor.dir/image")
+                            || type.equals("image/*")) {
                         mInclusion = ImageManager.INCLUDE_IMAGES;
-                        if (isPickIntent())
-                            leftText.setText(R.string.pick_photos_gallery_title);
-                        else
+                        if (isPickIntent()) {
+                            leftText.setText(
+                                    R.string.pick_photos_gallery_title);
+                        } else {
                             leftText.setText(R.string.photos_gallery_title);
+                        }
                     }
-                    if (type.equals("vnd.android.cursor.dir/video") || type.equals("video/*")) {
+                    if (type.equals("vnd.android.cursor.dir/video")
+                            || type.equals("video/*")) {
                         mInclusion = ImageManager.INCLUDE_VIDEOS;
-                        if (isPickIntent())
-                            leftText.setText(R.string.pick_videos_gallery_title);
-                        else
+                        if (isPickIntent()) {
+                            leftText.setText(
+                                    R.string.pick_videos_gallery_title);
+                        } else {
                             leftText.setText(R.string.videos_gallery_title);
+                        }
                     }
                 }
                 Bundle extras = intent.getExtras();
-                String title = extras!= null ? extras.getString("windowTitle") : null;
+                String title = (extras != null)
+                        ? extras.getString("windowTitle")
+                        : null;
                 if (title != null && title.length() > 0) {
                     leftText.setText(title);
                 }
 
                 if (extras != null) {
-                    mInclusion = (ImageManager.INCLUDE_IMAGES | ImageManager.INCLUDE_VIDEOS)
-                        & extras.getInt("mediaTypes", mInclusion);
+                    mInclusion = (ImageManager.INCLUDE_IMAGES
+                            | ImageManager.INCLUDE_VIDEOS)
+                            & extras.getInt("mediaTypes", mInclusion);
                 }
 
                 if (extras != null && extras.getBoolean("pick-drm")) {
@@ -723,9 +751,11 @@
                     mInclusion = ImageManager.INCLUDE_DRM_IMAGES;
                 }
             }
-            if (Config.LOGV)
-                Log.v(TAG, "computing images... mSortAscending is " + mSortAscending
-                        + "; assumeMounted is " + assumeMounted);
+            if (Config.LOGV) {
+                Log.v(TAG, "computing images... mSortAscending is "
+                        + mSortAscending + "; assumeMounted is "
+                        + assumeMounted);
+            }
             Uri uri = getIntent().getData();
             if (!assumeMounted) {
                 mAllImages = ImageManager.instance().emptyImageList();
@@ -735,1130 +765,1336 @@
                         getContentResolver(),
                         ImageManager.DataLocation.NONE,
                         mInclusion,
-                        mSortAscending ? ImageManager.SORT_ASCENDING : ImageManager.SORT_DESCENDING,
-                        uri != null ? uri.getQueryParameter("bucketId") : null);
+                        mSortAscending
+                        ? ImageManager.SORT_ASCENDING
+                        : ImageManager.SORT_DESCENDING,
+                        (uri != null)
+                        ? uri.getQueryParameter("bucketId")
+                        : null);
             }
         }
         return mAllImages;
     }
 
-    public static class GridViewSpecial extends View {
-        private ImageGallery2 mGallery;
-        private Paint   mGridViewPaint = new Paint();
-
-        private ImageBlockManager mImageBlockManager;
-        private Handler mHandler;
-
-        private LayoutSpec mCurrentSpec;
-        private boolean mShowSelection = false;
-        private int mCurrentSelection = -1;
-        private boolean mCurrentSelectionPressed;
-
-        private boolean mDirectionBiasDown = true;
-        private final static boolean sDump = false;
-
-        private long mVideoSizeLimit;
-
-        class LayoutSpec {
-            LayoutSpec(int cols, int w, int h, int leftEdgePadding, int rightEdgePadding, int intercellSpacing) {
-                mColumns = cols;
-                mCellWidth = w;
-                mCellHeight = h;
-                mLeftEdgePadding = leftEdgePadding;
-                mRightEdgePadding = rightEdgePadding;
-                mCellSpacing = intercellSpacing;
+    private class CreateContextMenuListener implements
+            View.OnCreateContextMenuListener {
+        public void onCreateContextMenu(ContextMenu menu, View v,
+                ContextMenu.ContextMenuInfo menuInfo) {
+            if (mSelectedImageGetter.getCurrentImage() == null) {
+                return;
             }
-            int mColumns;
-            int mCellWidth, mCellHeight;
-            int mLeftEdgePadding, mRightEdgePadding;
-            int mCellSpacing;
-        };
 
-        private LayoutSpec [] mCellSizeChoices = new LayoutSpec[] {
-                new LayoutSpec(0, 67, 67, 14, 14, 8),
-                new LayoutSpec(0, 92, 92, 14, 14, 8),
-        };
-        private int mSizeChoice = 1;
-
-        // Use a number like 100 or 200 here to allow the user to
-        // overshoot the start (top) or end (bottom) of the gallery.
-        // After overshooting the gallery will animate back to the
-        // appropriate location.
-        private int mMaxOvershoot = 0; // 100;
-        private int mMaxScrollY;
-        private int mMinScrollY;
-
-        private boolean mFling = true;
-        private Scroller mScroller = null;
-
-        private GestureDetector mGestureDetector;
-
-        public void dump() {
-            if (Config.LOGV){
-                Log.v(TAG, "mSizeChoice is " + mCellSizeChoices[mSizeChoice]);
-                Log.v(TAG, "mCurrentSpec.width / mCellHeight are " + mCurrentSpec.mCellWidth + " / " + mCurrentSpec.mCellHeight);
+            boolean isImage = ImageManager.isImage(
+                    mSelectedImageGetter.getCurrentImage());
+            if (isImage) {
+                menu.add(0, 0, 0, R.string.view).setOnMenuItemClickListener(
+                        new MenuItem.OnMenuItemClickListener() {
+                            public boolean onMenuItemClick(MenuItem item) {
+                                mGvs.onSelect(mGvs.mCurrentSelection);
+                                return true;
+                            }
+                        });
             }
-            mImageBlockManager.dump();
+
+            menu.setHeaderTitle(isImage
+                    ? R.string.context_menu_header
+                    : R.string.video_context_menu_header);
+            if ((mInclusion & (ImageManager.INCLUDE_IMAGES
+                    | ImageManager.INCLUDE_VIDEOS)) != 0) {
+                MenuHelper.MenuItemsResult r = MenuHelper.addImageMenuItems(
+                        menu,
+                        MenuHelper.INCLUDE_ALL,
+                        isImage,
+                        ImageGallery2.this,
+                        mHandler,
+                        mDeletePhotoRunnable,
+                        new MenuHelper.MenuInvoker() {
+                            public void run(MenuHelper.MenuCallback cb) {
+                                cb.run(mSelectedImageGetter
+                                        .getCurrentImageUri(),
+                                        mSelectedImageGetter.getCurrentImage());
+
+                                mGvs.clearCache();
+                                mGvs.invalidate();
+                                mGvs.requestLayout();
+                                mGvs.start();
+                                mNoImagesView.setVisibility(
+                                        mAllImages.getCount() > 0
+                                        ? View.GONE
+                                        : View.VISIBLE);
+                            }
+                        });
+                if (r != null) {
+                    r.gettingReadyToOpen(menu,
+                            mSelectedImageGetter.getCurrentImage());
+                }
+
+                if (isImage) {
+                    addSlideShowMenu(menu, 1000);
+                }
+            }
         }
+    }
+}
 
-        private void init(Context context) {
-            mGridViewPaint.setColor(0xFF000000);
-            mGallery = (ImageGallery2) context;
 
-            setVerticalScrollBarEnabled(true);
-            initializeScrollbars(context.obtainStyledAttributes(android.R.styleable.View));
+class GridViewSpecial extends View {
+    private static final String TAG = "GridViewSpecial";
+    ImageGallery2 mGallery;
+    private Paint   mGridViewPaint = new Paint();
 
-            mGestureDetector = new GestureDetector(context, new SimpleOnGestureListener() {
-                @Override
-                public boolean onDown(MotionEvent e) {
-                    if (mScroller != null && !mScroller.isFinished()) {
-                        mScroller.forceFinished(true);
-                        return false;
-                    }
+    ImageBlockManager mImageBlockManager;
+    private Handler mHandler;
 
-                    int pos = computeSelectedIndex(e);
-                    if (pos >= 0 && pos < mGallery.mAllImages.getCount()) {
-                        select(pos, true);
-                    } else {
-                        select(-1, false);
-                    }
-                    if (mImageBlockManager != null)
-                        mImageBlockManager.repaintSelection(mCurrentSelection);
-                    invalidate();
-                    return true;
-                }
+    LayoutSpec mCurrentSpec;
+    boolean mShowSelection = false;
+    int mCurrentSelection = -1;
+    private boolean mCurrentSelectionPressed;
 
-                @Override
-                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {
-                    final float maxVelocity = 2500;
-                    if (velocityY > maxVelocity)
-                        velocityY = maxVelocity;
-                    else if (velocityY < -maxVelocity)
-                        velocityY = -maxVelocity;
+    private boolean mDirectionBiasDown = true;
+    private static final boolean DUMP = false;
 
-                    select(-1, false);
-                    if (mFling) {
-                        mScroller = new Scroller(getContext());
-                        mScroller.fling(0, mScrollY, 0, -(int)velocityY, 0, 0, 0, mMaxScrollY);
-                        computeScroll();
-                    }
-                    return true;
-                }
+    long mVideoSizeLimit;
 
-                @Override
-                public void onLongPress(MotionEvent e) {
-                    performLongClick();
-                }
+    class LayoutSpec {
+        LayoutSpec(int cols, int w, int h, int leftEdgePadding,
+                   int rightEdgePadding, int intercellSpacing) {
+            mColumns = cols;
+            mCellWidth = w;
+            mCellHeight = h;
+            mLeftEdgePadding = leftEdgePadding;
+            mRightEdgePadding = rightEdgePadding;
+            mCellSpacing = intercellSpacing;
+        }
+        int mColumns;
+        int mCellWidth, mCellHeight;
+        int mLeftEdgePadding, mRightEdgePadding;
+        int mCellSpacing;
+    };
 
-                @Override
-                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) {
-                    select(-1, false);
-                    scrollBy(0, (int)distanceY);
-                    invalidate();
-                    return true;
-                }
+    private LayoutSpec [] mCellSizeChoices = new LayoutSpec[] {
+            new LayoutSpec(0, 67, 67, 14, 14, 8),
+            new LayoutSpec(0, 92, 92, 14, 14, 8),
+    };
+    private int mSizeChoice = 1;
 
-                @Override
-                public boolean onSingleTapUp(MotionEvent e) {
-                    select(mCurrentSelection, false);
-                    int index = computeSelectedIndex(e);
-                    if (index >= 0 && index < mGallery.mAllImages.getCount()) {
-                        onSelect(index);
-                        return true;
-                    }
+    // Use a number like 100 or 200 here to allow the user to
+    // overshoot the start (top) or end (bottom) of the gallery.
+    // After overshooting the gallery will animate back to the
+    // appropriate location.
+    private int mMaxOvershoot = 0; // 100;
+    private int mMaxScrollY;
+    private int mMinScrollY;
+
+    private boolean mFling = true;
+    private Scroller mScroller = null;
+
+    private GestureDetector mGestureDetector;
+
+    public void dump() {
+        if (Config.LOGV){
+            Log.v(TAG, "mSizeChoice is " + mCellSizeChoices[mSizeChoice]);
+            Log.v(TAG, "mCurrentSpec.width / mCellHeight are "
+                    + mCurrentSpec.mCellWidth + " / "
+                    + mCurrentSpec.mCellHeight);
+        }
+        mImageBlockManager.dump();
+    }
+
+    private void init(Context context) {
+        mGridViewPaint.setColor(0xFF000000);
+        mGallery = (ImageGallery2) context;
+
+        setVerticalScrollBarEnabled(true);
+        initializeScrollbars(context.obtainStyledAttributes(
+                android.R.styleable.View));
+
+        mGestureDetector = new GestureDetector(context,
+                new SimpleOnGestureListener() {
+            @Override
+            public boolean onDown(MotionEvent e) {
+                if (mScroller != null && !mScroller.isFinished()) {
+                    mScroller.forceFinished(true);
                     return false;
                 }
-            });
-//          mGestureDetector.setIsLongpressEnabled(false);
-        }
 
-        public GridViewSpecial(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
-            init(context);
-        }
-
-        public GridViewSpecial(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            init(context);
-        }
-
-        public GridViewSpecial(Context context) {
-            super(context);
-            init(context);
-        }
-
-        @Override
-        protected int computeVerticalScrollRange() {
-            return mMaxScrollY + getHeight();
-        }
-
-        public void setSizeChoice(int choice, int scrollY) {
-            mSizeChoice = choice;
-            clearCache();
-            scrollTo(0, scrollY);
-            requestLayout();
-            invalidate();
-        }
-
-        /**
-         *
-         * @param newSel -2 means use old selection, -1 means remove selection
-         * @param newPressed
-         */
-        public void select(int newSel, boolean newPressed) {
-            if (newSel == -2) {
-                newSel = mCurrentSelection;
-            }
-            int oldSel = mCurrentSelection;
-            if ((oldSel == newSel) && (mCurrentSelectionPressed == newPressed))
-                return;
-
-            mShowSelection = (newSel != -1);
-            mCurrentSelection = newSel;
-            mCurrentSelectionPressed = newPressed;
-            if (mImageBlockManager != null) {
-                mImageBlockManager.repaintSelection(oldSel);
-                mImageBlockManager.repaintSelection(newSel);
-            }
-
-            if (newSel != -1)
-                ensureVisible(newSel);
-        }
-
-        private void ensureVisible(int pos) {
-            android.graphics.Rect r = getRectForPosition(pos);
-            int top = getScrollY();
-            int bot = top + getHeight();
-
-            if (r.bottom > bot) {
-                mScroller = new Scroller(getContext());
-                mScroller.startScroll(mScrollX, mScrollY, 0, r.bottom - getHeight() - mScrollY, 200);
-                computeScroll();
-            } else if (r.top < top) {
-                mScroller = new Scroller(getContext());
-                mScroller.startScroll(mScrollX, mScrollY, 0, r.top - mScrollY, 200);
-                computeScroll();
-            }
-            invalidate();
-        }
-
-        public void start() {
-            if (mGallery.mLayoutComplete) {
-                if (mImageBlockManager == null) {
-                    mImageBlockManager = new ImageBlockManager();
-                    mImageBlockManager.moveDataWindow(true, true);
-                }
-            }
-        }
-
-        public void onPause() {
-            mScroller = null;
-            if (mImageBlockManager != null) {
-                mImageBlockManager.onPause();
-                mImageBlockManager = null;
-            }
-        }
-
-        public void clearCache() {
-            if (mImageBlockManager != null) {
-                mImageBlockManager.onPause();
-                mImageBlockManager = null;
-            }
-        }
-
-
-        @Override
-        public void onLayout(boolean changed, int left, int top, int right, int bottom) {
-            super.onLayout(changed, left, top, right, bottom);
-
-            if (mGallery.isFinishing() || mGallery.mPausing) {
-                return;
-            }
-
-            clearCache();
-
-            mCurrentSpec = mCellSizeChoices[mSizeChoice];
-            int oldColumnCount = mCurrentSpec.mColumns;
-
-            int width = right - left;
-            mCurrentSpec.mColumns = 1;
-            width -= mCurrentSpec.mCellWidth;
-            mCurrentSpec.mColumns += width / (mCurrentSpec.mCellWidth + mCurrentSpec.mCellSpacing);
-
-            mCurrentSpec.mLeftEdgePadding = ((right - left) - ((mCurrentSpec.mColumns - 1) * mCurrentSpec.mCellSpacing) - (mCurrentSpec.mColumns * mCurrentSpec.mCellWidth)) / 2;
-            mCurrentSpec.mRightEdgePadding = mCurrentSpec.mLeftEdgePadding;
-
-            int rows = (mGallery.mAllImages.getCount() + mCurrentSpec.mColumns - 1) / mCurrentSpec.mColumns;
-            mMaxScrollY = mCurrentSpec.mCellSpacing + (rows * (mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight)) - (bottom - top) + mMaxOvershoot;
-            mMinScrollY = 0 - mMaxOvershoot;
-
-            mGallery.mLayoutComplete = true;
-
-            start();
-
-            if (mGallery.mSortAscending && mGallery.mTargetScroll == 0) {
-                scrollTo(0, mMaxScrollY - mMaxOvershoot);
-            } else {
-                if (oldColumnCount != 0) {
-                    int y = mGallery.mTargetScroll * oldColumnCount / mCurrentSpec.mColumns;
-                    Log.v(TAG, "target was " + mGallery.mTargetScroll + " now " + y);
-                    scrollTo(0, y);
-                }
-            }
-        }
-
-        Bitmap scaleTo(int width, int height, Bitmap b) {
-            Matrix m = new Matrix();
-            m.setScale((float)width/64F, (float)height/64F);
-            Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
-            if (b2 != b)
-                b.recycle();
-            return b2;
-        }
-
-        private class ImageBlockManager {
-            private ImageLoader mLoader;
-            private int mBlockCacheFirstBlockNumber = 0;
-
-            // mBlockCache is an array with a starting point which is not necessaryily
-            // zero.  The first element of the array is indicated by mBlockCacheStartOffset.
-            private int mBlockCacheStartOffset = 0;
-            private ImageBlock [] mBlockCache;
-
-            private static final int sRowsPerPage    = 6;   // should compute this
-
-            private static final int sPagesPreCache  = 2;
-            private static final int sPagesPostCache = 2;
-
-            private int mWorkCounter = 0;
-            private boolean mDone = false;
-
-            private Thread mWorkerThread;
-            private Bitmap mMissingImageThumbnailBitmap;
-            private Bitmap mMissingVideoThumbnailBitmap;
-
-            private Drawable mVideoOverlay;
-            private Drawable mVideoMmsErrorOverlay;
-
-            public void dump() {
-                synchronized (ImageBlockManager.this) {
-                    StringBuilder line1 = new StringBuilder();
-                    StringBuilder line2 = new StringBuilder();
-                    if (Config.LOGV)
-                        Log.v(TAG, ">>> mBlockCacheFirstBlockNumber: " + mBlockCacheFirstBlockNumber + " " + mBlockCacheStartOffset);
-                    for (int i = 0; i < mBlockCache.length; i++) {
-                        int index = (mBlockCacheStartOffset + i) % mBlockCache.length;
-                        ImageBlock block = mBlockCache[index];
-                        block.dump(line1, line2);
-                    }
-                    if (Config.LOGV){
-                        Log.v(TAG, line1.toString());
-                        Log.v(TAG, line2.toString());
-                    }
-                }
-            }
-
-            ImageBlockManager() {
-                mLoader = new ImageLoader(mHandler, 1);
-
-                mBlockCache = new ImageBlock[sRowsPerPage * (sPagesPreCache + sPagesPostCache + 1)];
-                for (int i = 0; i < mBlockCache.length; i++) {
-                    mBlockCache[i] = new ImageBlock();
-                }
-
-                mWorkerThread = new Thread(new Runnable() {
-                    public void run() {
-                        while (true) {
-                            int workCounter;
-                            synchronized (ImageBlockManager.this) {
-                                workCounter = mWorkCounter;
-                            }
-                            if (mDone) {
-                                if (Config.LOGV)
-                                    Log.v(TAG, "stopping the loader here " + Thread.currentThread().getName());
-                                if (mLoader != null) {
-                                    mLoader.stop();
-                                }
-                                if (mBlockCache != null) {
-                                    for (int i = 0; i < mBlockCache.length; i++) {
-                                        ImageBlock block = mBlockCache[i];
-                                        if (block != null) {
-                                            block.recycleBitmaps();
-                                            mBlockCache[i] = null;
-                                        }
-                                    }
-                                }
-                                mBlockCache = null;
-                                mBlockCacheStartOffset = 0;
-                                mBlockCacheFirstBlockNumber = 0;
-
-                                break;
-                            }
-
-                            loadNext();
-
-                            synchronized (ImageBlockManager.this) {
-                                if ((workCounter == mWorkCounter) && (! mDone)) {
-                                    try {
-                                        ImageBlockManager.this.wait();
-                                    } catch (InterruptedException ex) {
-                                    }
-                                }
-                            }
-                        }
-                    }
-                });
-                mWorkerThread.setName("image-block-manager");
-                mWorkerThread.start();
-            }
-
-            // Create this bitmap lazily, and only once for all the ImageBlocks to use
-            public Bitmap getErrorBitmap(IImage image) {
-                if (ImageManager.isImage(image)) {
-                    if (mMissingImageThumbnailBitmap == null) {
-                        mMissingImageThumbnailBitmap = BitmapFactory.decodeResource(GridViewSpecial.this.getResources(),
-                                R.drawable.ic_missing_thumbnail_picture);
-                    }
-                    return mMissingImageThumbnailBitmap;
+                int pos = computeSelectedIndex(e);
+                if (pos >= 0 && pos < mGallery.mAllImages.getCount()) {
+                    select(pos, true);
                 } else {
-                    if (mMissingVideoThumbnailBitmap == null) {
-                        mMissingVideoThumbnailBitmap = BitmapFactory.decodeResource(GridViewSpecial.this.getResources(),
-                                R.drawable.ic_missing_thumbnail_video);
-                    }
-                    return mMissingVideoThumbnailBitmap;
+                    select(-1, false);
                 }
+                if (mImageBlockManager != null) {
+                    mImageBlockManager.repaintSelection(mCurrentSelection);
+                }
+                invalidate();
+                return true;
             }
 
-            private ImageBlock getBlockForPos(int pos) {
-                synchronized (ImageBlockManager.this) {
-                    int blockNumber = pos / mCurrentSpec.mColumns;
-                    int delta = blockNumber - mBlockCacheFirstBlockNumber;
-                    if (delta >= 0 && delta < mBlockCache.length) {
-                        int index = (mBlockCacheStartOffset + delta) % mBlockCache.length;
-                        ImageBlock b = mBlockCache[index];
-                        return b;
-                    }
+            @Override
+            public boolean onFling(MotionEvent e1, MotionEvent e2,
+                    float velocityX, float velocityY) {
+                final float maxVelocity = 2500;
+                if (velocityY > maxVelocity) {
+                    velocityY = maxVelocity;
+                } else if (velocityY < -maxVelocity) {
+                    velocityY = -maxVelocity;
                 }
-                return null;
+
+                select(-1, false);
+                if (mFling) {
+                    mScroller = new Scroller(getContext());
+                    mScroller.fling(0, mScrollY, 0, -(int) velocityY, 0, 0, 0,
+                            mMaxScrollY);
+                    computeScroll();
+                }
+                return true;
             }
 
-            private void repaintSelection(int pos) {
-                synchronized (ImageBlockManager.this) {
-                    ImageBlock b = getBlockForPos(pos);
-                    if (b != null) {
-                        b.repaintSelection();
-                    }
-                }
+            @Override
+            public void onLongPress(MotionEvent e) {
+                performLongClick();
             }
 
-            private void onPause() {
-                synchronized (ImageBlockManager.this) {
-                    mDone = true;
-                    ImageBlockManager.this.notify();
-                }
-                if (mWorkerThread != null) {
-                    try {
-                        mWorkerThread.join();
-                        mWorkerThread = null;
-                    } catch (InterruptedException ex) {
-                        //
-                    }
-                }
-                Log.v(TAG, "/ImageBlockManager.onPause");
+            @Override
+            public boolean onScroll(MotionEvent e1, MotionEvent e2,
+                                    float distanceX, float distanceY) {
+                select(-1, false);
+                scrollBy(0, (int) distanceY);
+                invalidate();
+                return true;
             }
 
-            private void getVisibleRange(int [] range) {
-                // try to work around a possible bug in the VM wherein this appears to be null
-                try {
-                    synchronized (ImageBlockManager.this) {
-                        int blockLength = mBlockCache.length;
-                        boolean lookingForStart = true;
-                        ImageBlock prevBlock = null;
-                        for (int i = 0; i < blockLength; i++) {
-                            int index = (mBlockCacheStartOffset + i) % blockLength;
-                            ImageBlock block = mBlockCache[index];
-                            if (lookingForStart) {
-                                if (block.mIsVisible) {
-                                    range[0] = block.mBlockNumber * mCurrentSpec.mColumns;
-                                    lookingForStart = false;
-                                }
-                            } else {
-                                if (!block.mIsVisible || i == blockLength - 1) {
-                                    range[1] = (prevBlock.mBlockNumber * mCurrentSpec.mColumns) + mCurrentSpec.mColumns - 1;
-                                    break;
+            @Override
+            public boolean onSingleTapUp(MotionEvent e) {
+                select(mCurrentSelection, false);
+                int index = computeSelectedIndex(e);
+                if (index >= 0 && index < mGallery.mAllImages.getCount()) {
+                    onSelect(index);
+                    return true;
+                }
+                return false;
+            }
+        });
+        // mGestureDetector.setIsLongpressEnabled(false);
+    }
+
+    public GridViewSpecial(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context);
+    }
+
+    public GridViewSpecial(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public GridViewSpecial(Context context) {
+        super(context);
+        init(context);
+    }
+
+    @Override
+    protected int computeVerticalScrollRange() {
+        return mMaxScrollY + getHeight();
+    }
+
+    public void setSizeChoice(int choice, int scrollY) {
+        mSizeChoice = choice;
+        clearCache();
+        scrollTo(0, scrollY);
+        requestLayout();
+        invalidate();
+    }
+
+    /**
+     *
+     * @param newSel -2 means use old selection, -1 means remove selection
+     * @param newPressed
+     */
+    public void select(int newSel, boolean newPressed) {
+        if (newSel == -2) {
+            newSel = mCurrentSelection;
+        }
+        int oldSel = mCurrentSelection;
+        if ((oldSel == newSel) && (mCurrentSelectionPressed == newPressed)) {
+            return;
+        }
+
+        mShowSelection = (newSel != -1);
+        mCurrentSelection = newSel;
+        mCurrentSelectionPressed = newPressed;
+        if (mImageBlockManager != null) {
+            mImageBlockManager.repaintSelection(oldSel);
+            mImageBlockManager.repaintSelection(newSel);
+        }
+
+        if (newSel != -1) {
+            ensureVisible(newSel);
+        }
+    }
+
+    private void ensureVisible(int pos) {
+        android.graphics.Rect r = getRectForPosition(pos);
+        int top = getScrollY();
+        int bot = top + getHeight();
+
+        if (r.bottom > bot) {
+            mScroller = new Scroller(getContext());
+            mScroller.startScroll(mScrollX, mScrollY, 0,
+                    r.bottom - getHeight() - mScrollY, 200);
+            computeScroll();
+        } else if (r.top < top) {
+            mScroller = new Scroller(getContext());
+            mScroller.startScroll(mScrollX, mScrollY, 0, r.top - mScrollY, 200);
+            computeScroll();
+        }
+        invalidate();
+    }
+
+    public void start() {
+        if (mGallery.mLayoutComplete) {
+            if (mImageBlockManager == null) {
+                mImageBlockManager = new ImageBlockManager();
+                mImageBlockManager.moveDataWindow(true, true);
+            }
+        }
+    }
+
+    public void onPause() {
+        mScroller = null;
+        if (mImageBlockManager != null) {
+            mImageBlockManager.onPause();
+            mImageBlockManager = null;
+        }
+    }
+
+    public void clearCache() {
+        if (mImageBlockManager != null) {
+            mImageBlockManager.onPause();
+            mImageBlockManager = null;
+        }
+    }
+
+
+    @Override
+    public void onLayout(boolean changed, int left, int top,
+                         int right, int bottom) {
+        super.onLayout(changed, left, top, right, bottom);
+
+        if (mGallery.isFinishing() || mGallery.mPausing) {
+            return;
+        }
+
+        clearCache();
+
+        mCurrentSpec = mCellSizeChoices[mSizeChoice];
+        int oldColumnCount = mCurrentSpec.mColumns;
+
+        int width = right - left;
+        mCurrentSpec.mColumns = 1;
+        width -= mCurrentSpec.mCellWidth;
+        mCurrentSpec.mColumns += width
+                / (mCurrentSpec.mCellWidth + mCurrentSpec.mCellSpacing);
+
+        mCurrentSpec.mLeftEdgePadding = ((right - left)
+                - ((mCurrentSpec.mColumns - 1) * mCurrentSpec.mCellSpacing)
+                - (mCurrentSpec.mColumns * mCurrentSpec.mCellWidth)) / 2;
+        mCurrentSpec.mRightEdgePadding = mCurrentSpec.mLeftEdgePadding;
+
+        int rows = (mGallery.mAllImages.getCount() + mCurrentSpec.mColumns - 1)
+                / mCurrentSpec.mColumns;
+        mMaxScrollY = mCurrentSpec.mCellSpacing
+                + (rows
+                * (mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight))
+                - (bottom - top) + mMaxOvershoot;
+        mMinScrollY = 0 - mMaxOvershoot;
+
+        mGallery.mLayoutComplete = true;
+
+        start();
+
+        if (mGallery.mSortAscending && mGallery.mTargetScroll == 0) {
+            scrollTo(0, mMaxScrollY - mMaxOvershoot);
+        } else {
+            if (oldColumnCount != 0) {
+                int y = mGallery.mTargetScroll *
+                        oldColumnCount / mCurrentSpec.mColumns;
+                Log.v(TAG, "target was " + mGallery.mTargetScroll
+                        + " now " + y);
+                scrollTo(0, y);
+            }
+        }
+    }
+
+    Bitmap scaleTo(int width, int height, Bitmap b) {
+        Matrix m = new Matrix();
+        m.setScale((float) width / 64F, (float) height / 64F);
+        Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(),
+                m, false);
+        if (b2 != b) {
+            b.recycle();
+        }
+        return b2;
+    }
+
+    class ImageBlockManager {
+        private ImageLoader mLoader;
+        private int mBlockCacheFirstBlockNumber = 0;
+
+        // mBlockCache is an array with a starting point which is not
+        // necessarily zero.  The first element of the array is indicated by
+        // mBlockCacheStartOffset.
+        private int mBlockCacheStartOffset = 0;
+        private ImageBlock [] mBlockCache;
+
+        private static final int sRowsPerPage    = 6;   // should compute this
+
+        private static final int sPagesPreCache  = 2;
+        private static final int sPagesPostCache = 2;
+
+        private int mWorkCounter = 0;
+        private boolean mDone = false;
+
+        private Thread mWorkerThread;
+        private Bitmap mMissingImageThumbnailBitmap;
+        private Bitmap mMissingVideoThumbnailBitmap;
+
+        private Drawable mVideoOverlay;
+        private Drawable mVideoMmsErrorOverlay;
+
+        public void dump() {
+            synchronized (ImageBlockManager.this) {
+                StringBuilder line1 = new StringBuilder();
+                StringBuilder line2 = new StringBuilder();
+                if (Config.LOGV) {
+                    Log.v(TAG, ">>> mBlockCacheFirstBlockNumber: "
+                            + mBlockCacheFirstBlockNumber + " "
+                            + mBlockCacheStartOffset);
+                }
+                for (int i = 0; i < mBlockCache.length; i++) {
+                    int index = (mBlockCacheStartOffset + i)
+                            % mBlockCache.length;
+                    ImageBlock block = mBlockCache[index];
+                    block.dump(line1, line2);
+                }
+                if (Config.LOGV){
+                    Log.v(TAG, line1.toString());
+                    Log.v(TAG, line2.toString());
+                }
+            }
+        }
+
+        ImageBlockManager() {
+            mLoader = new ImageLoader(mHandler, 1);
+
+            mBlockCache = new ImageBlock[sRowsPerPage
+                    * (sPagesPreCache + sPagesPostCache + 1)];
+            for (int i = 0; i < mBlockCache.length; i++) {
+                mBlockCache[i] = new ImageBlock();
+            }
+
+            mWorkerThread = new Thread(new Runnable() {
+                public void run() {
+                    while (true) {
+                        int workCounter;
+                        synchronized (ImageBlockManager.this) {
+                            workCounter = mWorkCounter;
+                        }
+                        if (mDone) {
+                            if (Config.LOGV) {
+                                Log.v(TAG, "stopping the loader here "
+                                        + Thread.currentThread().getName());
+                            }
+                            if (mLoader != null) {
+                                mLoader.stop();
+                            }
+                            if (mBlockCache != null) {
+                                for (int i = 0; i < mBlockCache.length; i++) {
+                                    ImageBlock block = mBlockCache[i];
+                                    if (block != null) {
+                                        block.recycleBitmaps();
+                                        mBlockCache[i] = null;
+                                    }
                                 }
                             }
-                            prevBlock = block;
+                            mBlockCache = null;
+                            mBlockCacheStartOffset = 0;
+                            mBlockCacheFirstBlockNumber = 0;
+
+                            break;
+                        }
+
+                        loadNext();
+
+                        synchronized (ImageBlockManager.this) {
+                            if ((workCounter == mWorkCounter) && (!mDone)) {
+                                try {
+                                    ImageBlockManager.this.wait();
+                                } catch (InterruptedException ex) {
+                                }
+                            }
                         }
                     }
-                } catch (NullPointerException ex) {
-                    Log.e(TAG, "this is somewhat null, what up?");
-                    range[0] = range[1] = 0;
+                }
+            });
+            mWorkerThread.setName("image-block-manager");
+            mWorkerThread.start();
+        }
+
+        // Create this bitmap lazily, and only once for all the ImageBlocks to
+        // use
+        public Bitmap getErrorBitmap(IImage image) {
+            if (ImageManager.isImage(image)) {
+                if (mMissingImageThumbnailBitmap == null) {
+                    mMissingImageThumbnailBitmap =
+                            BitmapFactory.decodeResource(
+                            GridViewSpecial.this.getResources(),
+                            R.drawable.ic_missing_thumbnail_picture);
+                }
+                return mMissingImageThumbnailBitmap;
+            } else {
+                if (mMissingVideoThumbnailBitmap == null) {
+                    mMissingVideoThumbnailBitmap =
+                            BitmapFactory.decodeResource(
+                            GridViewSpecial.this.getResources(),
+                            R.drawable.ic_missing_thumbnail_video);
+                }
+                return mMissingVideoThumbnailBitmap;
+            }
+        }
+
+        private ImageBlock getBlockForPos(int pos) {
+            synchronized (ImageBlockManager.this) {
+                int blockNumber = pos / mCurrentSpec.mColumns;
+                int delta = blockNumber - mBlockCacheFirstBlockNumber;
+                if (delta >= 0 && delta < mBlockCache.length) {
+                    int index = (mBlockCacheStartOffset + delta)
+                            % mBlockCache.length;
+                    ImageBlock b = mBlockCache[index];
+                    return b;
                 }
             }
+            return null;
+        }
 
-            private void loadNext() {
-                final int blockHeight = (mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight);
+        private void repaintSelection(int pos) {
+            synchronized (ImageBlockManager.this) {
+                ImageBlock b = getBlockForPos(pos);
+                if (b != null) {
+                    b.repaintSelection();
+                }
+            }
+        }
 
-                final int firstVisBlock = Math.max(0, (mScrollY - mCurrentSpec.mCellSpacing) / blockHeight);
-                final int lastVisBlock  = (mScrollY - mCurrentSpec.mCellSpacing + getHeight()) / blockHeight;
+        private void onPause() {
+            synchronized (ImageBlockManager.this) {
+                mDone = true;
+                ImageBlockManager.this.notify();
+            }
+            if (mWorkerThread != null) {
+                try {
+                    mWorkerThread.join();
+                    mWorkerThread = null;
+                } catch (InterruptedException ex) {
+                    //
+                }
+            }
+            Log.v(TAG, "/ImageBlockManager.onPause");
+        }
 
-//              Log.v(TAG, "firstVisBlock == " + firstVisBlock + "; lastVisBlock == " + lastVisBlock);
-
+        void getVisibleRange(int [] range) {
+            // try to work around a possible bug in the VM wherein this appears
+            // to be null
+            try {
                 synchronized (ImageBlockManager.this) {
-                    ImageBlock [] blocks = mBlockCache;
-                    int numBlocks = blocks.length;
-                    if (mDirectionBiasDown) {
-                        int first = (mBlockCacheStartOffset + (firstVisBlock - mBlockCacheFirstBlockNumber)) % blocks.length;
-                        for (int i = 0; i < numBlocks; i++) {
-                            int j = first + i;
-                            if (j >= numBlocks)
-                                j -= numBlocks;
-                            ImageBlock b = blocks[j];
-                            if (b.startLoading() > 0)
-                                break;
-                        }
-                    } else {
-                        int first = (mBlockCacheStartOffset + (lastVisBlock - mBlockCacheFirstBlockNumber)) % blocks.length;
-                        for (int i = 0; i < numBlocks; i++) {
-                            int j = first - i;
-                            if (j < 0)
-                                j += numBlocks;
-                            ImageBlock b = blocks[j];
-                            if (b.startLoading() > 0)
-                                break;
-                        }
-                    }
-                    if (sDump)
-                        this.dump();
-                }
-            }
-
-            private void moveDataWindow(boolean directionBiasDown, boolean forceRefresh) {
-                final int blockHeight = (mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight);
-
-                final int firstVisBlock = (mScrollY - mCurrentSpec.mCellSpacing) / blockHeight;
-                final int lastVisBlock  = (mScrollY - mCurrentSpec.mCellSpacing + getHeight()) / blockHeight;
-
-                final int preCache = sPagesPreCache;
-                final int startBlock = Math.max(0, firstVisBlock - (preCache * sRowsPerPage));
-
-//              Log.v(TAG, "moveDataWindow directionBiasDown == " + directionBiasDown + "; preCache is " + preCache);
-                synchronized (ImageBlockManager.this) {
-                    boolean any = false;
-                    ImageBlock [] blocks = mBlockCache;
-                    int numBlocks = blocks.length;
-
-                    int delta = startBlock - mBlockCacheFirstBlockNumber;
-
-                    mBlockCacheFirstBlockNumber = startBlock;
-                    if (Math.abs(delta) > numBlocks || forceRefresh) {
-                        for (int i = 0; i < numBlocks; i++) {
-                            int blockNum = startBlock + i;
-                            blocks[i].setStart(blockNum);
-                            any = true;
-                        }
-                        mBlockCacheStartOffset = 0;
-                    } else if (delta > 0) {
-                        mBlockCacheStartOffset += delta;
-                        if (mBlockCacheStartOffset >= numBlocks)
-                            mBlockCacheStartOffset -= numBlocks;
-
-                        for (int i = delta; i > 0; i--) {
-                            int index = (mBlockCacheStartOffset + numBlocks - i) % numBlocks;
-                            int blockNum = mBlockCacheFirstBlockNumber + numBlocks - i;
-                            blocks[index].setStart(blockNum);
-                            any = true;
-                        }
-                    } else if (delta < 0) {
-                        mBlockCacheStartOffset += delta;
-                        if (mBlockCacheStartOffset < 0)
-                            mBlockCacheStartOffset += numBlocks;
-
-                        for (int i = 0; i < -delta; i++) {
-                            int index = (mBlockCacheStartOffset + i) % numBlocks;
-                            int blockNum = mBlockCacheFirstBlockNumber + i;
-                            blocks[index].setStart(blockNum);
-                            any = true;
-                        }
-                    }
-
-                    for (int i = 0; i < numBlocks; i++) {
-                        int index = (mBlockCacheStartOffset + i) % numBlocks;
-                        ImageBlock block = blocks[index];
-                        int blockNum = block.mBlockNumber; // mBlockCacheFirstBlockNumber + i;
-                        boolean isVis = blockNum >= firstVisBlock && blockNum <= lastVisBlock;
-//                      Log.v(TAG, "blockNum " + blockNum + " setting vis to " + isVis);
-                        block.setVisibility(isVis);
-                    }
-
-                    if (sDump)
-                        mImageBlockManager.dump();
-
-                    if (any) {
-                        ImageBlockManager.this.notify();
-                        mWorkCounter += 1;
-                    }
-                }
-                if (sDump)
-                    dump();
-            }
-
-            private void check() {
-                ImageBlock [] blocks = mBlockCache;
-                int blockLength = blocks.length;
-
-                // check the results
-                for (int i = 0; i < blockLength; i++) {
-                    int index = (mBlockCacheStartOffset + i) % blockLength;
-                    if (blocks[index].mBlockNumber != mBlockCacheFirstBlockNumber + i) {
-                        if (blocks[index].mBlockNumber != -1)
-                            Log.e(TAG, "at " + i + " block cache corrupted; found " + blocks[index].mBlockNumber + " but wanted " + (mBlockCacheFirstBlockNumber + i) + "; offset is " + mBlockCacheStartOffset);
-                    }
-                }
-                if (true) {
-                    StringBuilder sb  = new StringBuilder();
+                    int blockLength = mBlockCache.length;
+                    boolean lookingForStart = true;
+                    ImageBlock prevBlock = null;
                     for (int i = 0; i < blockLength; i++) {
                         int index = (mBlockCacheStartOffset + i) % blockLength;
-                        ImageBlock b = blocks[index];
-                        if (b.mRequestedMask != 0)
-                            sb.append("X");
-                        else
-                            sb.append(String.valueOf(b.mBlockNumber) + " ");
+                        ImageBlock block = mBlockCache[index];
+                        if (lookingForStart) {
+                            if (block.mIsVisible) {
+                                range[0] = block.mBlockNumber
+                                        * mCurrentSpec.mColumns;
+                                lookingForStart = false;
+                            }
+                        } else {
+                            if (!block.mIsVisible || i == blockLength - 1) {
+                                range[1] = (prevBlock.mBlockNumber
+                                        * mCurrentSpec.mColumns)
+                                        + mCurrentSpec.mColumns - 1;
+                                break;
+                            }
+                        }
+                        prevBlock = block;
                     }
-                    if (Config.LOGV)
-                        Log.v(TAG, "moveDataWindow " + sb.toString());
+                }
+            } catch (NullPointerException ex) {
+                Log.e(TAG, "this is somewhat null, what up?");
+                range[0] = range[1] = 0;
+            }
+        }
+
+        private void loadNext() {
+            final int blockHeight = (mCurrentSpec.mCellSpacing
+                    + mCurrentSpec.mCellHeight);
+
+            final int firstVisBlock =
+                    Math.max(0, (mScrollY - mCurrentSpec.mCellSpacing)
+                    / blockHeight);
+            final int lastVisBlock = 
+                    (mScrollY - mCurrentSpec.mCellSpacing + getHeight())
+                    / blockHeight;
+
+            synchronized (ImageBlockManager.this) {
+                ImageBlock [] blocks = mBlockCache;
+                int numBlocks = blocks.length;
+                if (mDirectionBiasDown) {
+                    int first = (mBlockCacheStartOffset
+                            + (firstVisBlock - mBlockCacheFirstBlockNumber))
+                            % blocks.length;
+                    for (int i = 0; i < numBlocks; i++) {
+                        int j = first + i;
+                        if (j >= numBlocks) {
+                            j -= numBlocks;
+                        }
+                        ImageBlock b = blocks[j];
+                        if (b.startLoading() > 0) {
+                            break;
+                        }
+                    }
+                } else {
+                    int first = (mBlockCacheStartOffset
+                            + (lastVisBlock - mBlockCacheFirstBlockNumber))
+                            % blocks.length;
+                    for (int i = 0; i < numBlocks; i++) {
+                        int j = first - i;
+                        if (j < 0) {
+                            j += numBlocks;
+                        }
+                        ImageBlock b = blocks[j];
+                        if (b.startLoading() > 0) {
+                            break;
+                        }
+                    }
+                }
+                if (DUMP) {
+                    this.dump();
+                }
+            }
+        }
+
+        private void moveDataWindow(boolean directionBiasDown,
+                boolean forceRefresh) {
+            final int blockHeight = (mCurrentSpec.mCellSpacing
+                    + mCurrentSpec.mCellHeight);
+
+            final int firstVisBlock = (mScrollY - mCurrentSpec.mCellSpacing)
+                    / blockHeight;
+            final int lastVisBlock =
+                    (mScrollY - mCurrentSpec.mCellSpacing + getHeight())
+                    / blockHeight;
+
+            final int preCache = sPagesPreCache;
+            final int startBlock = Math.max(0,
+                    firstVisBlock - (preCache * sRowsPerPage));
+
+            synchronized (ImageBlockManager.this) {
+                boolean any = false;
+                ImageBlock [] blocks = mBlockCache;
+                int numBlocks = blocks.length;
+
+                int delta = startBlock - mBlockCacheFirstBlockNumber;
+
+                mBlockCacheFirstBlockNumber = startBlock;
+                if (Math.abs(delta) > numBlocks || forceRefresh) {
+                    for (int i = 0; i < numBlocks; i++) {
+                        int blockNum = startBlock + i;
+                        blocks[i].setStart(blockNum);
+                        any = true;
+                    }
+                    mBlockCacheStartOffset = 0;
+                } else if (delta > 0) {
+                    mBlockCacheStartOffset += delta;
+                    if (mBlockCacheStartOffset >= numBlocks) {
+                        mBlockCacheStartOffset -= numBlocks;
+                    }
+
+                    for (int i = delta; i > 0; i--) {
+                        int index = (mBlockCacheStartOffset + numBlocks - i)
+                                % numBlocks;
+                        int blockNum = mBlockCacheFirstBlockNumber
+                                + numBlocks - i;
+                        blocks[index].setStart(blockNum);
+                        any = true;
+                    }
+                } else if (delta < 0) {
+                    mBlockCacheStartOffset += delta;
+                    if (mBlockCacheStartOffset < 0) {
+                        mBlockCacheStartOffset += numBlocks;
+                    }
+
+                    for (int i = 0; i < -delta; i++) {
+                        int index = (mBlockCacheStartOffset + i) % numBlocks;
+                        int blockNum = mBlockCacheFirstBlockNumber + i;
+                        blocks[index].setStart(blockNum);
+                        any = true;
+                    }
+                }
+
+                for (int i = 0; i < numBlocks; i++) {
+                    int index = (mBlockCacheStartOffset + i) % numBlocks;
+                    ImageBlock block = blocks[index];
+                    int blockNum = block.mBlockNumber; 
+                    boolean isVis = blockNum >= firstVisBlock
+                            && blockNum <= lastVisBlock;
+                    block.setVisibility(isVis);
+                }
+
+                if (DUMP) {
+                    mImageBlockManager.dump();
+                }
+
+                if (any) {
+                    ImageBlockManager.this.notify();
+                    mWorkCounter += 1;
+                }
+            }
+            if (DUMP) {
+                dump();
+            }
+        }
+
+        private void check() {
+            ImageBlock [] blocks = mBlockCache;
+            int blockLength = blocks.length;
+
+            // check the results
+            for (int i = 0; i < blockLength; i++) {
+                int index = (mBlockCacheStartOffset + i) % blockLength;
+                if (blocks[index].mBlockNumber
+                        != mBlockCacheFirstBlockNumber + i) {
+                    if (blocks[index].mBlockNumber != -1) {
+                        Log.e(TAG, "at " + i
+                                + " block cache corrupted; found "
+                                + blocks[index].mBlockNumber
+                                + " but wanted "
+                                + (mBlockCacheFirstBlockNumber + i)
+                                + "; offset is " + mBlockCacheStartOffset);
+                    }
+                }
+            }
+            if (true) {
+                StringBuilder sb  = new StringBuilder();
+                for (int i = 0; i < blockLength; i++) {
+                    int index = (mBlockCacheStartOffset + i) % blockLength;
+                    ImageBlock b = blocks[index];
+                    if (b.mRequestedMask != 0) {
+                        sb.append("X");
+                    } else {
+                        sb.append(String.valueOf(b.mBlockNumber) + " ");
+                    }
+                }
+                if (Config.LOGV) {
+                    Log.v(TAG, "moveDataWindow " + sb.toString());
+                }
+            }
+        }
+
+        void doDraw(Canvas canvas) {
+            synchronized (ImageBlockManager.this) {
+                ImageBlockManager.ImageBlock [] blocks = mBlockCache;
+                int blockCount = 0;
+
+                if (blocks[0] == null) {
+                    return;
+                }
+
+                final int thisHeight = getHeight();
+                final int thisWidth  = getWidth();
+                final int height = blocks[0].mBitmap.getHeight();
+                final int scrollPos = mScrollY;
+
+                int currentBlock = (scrollPos < 0)
+                        ? ((scrollPos - height + 1) / height)
+                        : (scrollPos / height);
+
+                while (true) {
+                    final int yPos = currentBlock * height;
+                    if (yPos >= scrollPos + thisHeight) {
+                        break;
+                    }
+
+                    if (currentBlock < 0) {
+                        canvas.drawRect(0, yPos, thisWidth, 0, mGridViewPaint);
+                        currentBlock += 1;
+                        continue;
+                    }
+                    int effectiveOffset = 
+                            (mBlockCacheStartOffset 
+                            + (currentBlock++ - mBlockCacheFirstBlockNumber)) 
+                            % blocks.length;
+                    if (effectiveOffset < 0 
+                            || effectiveOffset >= blocks.length) {
+                        break;
+                    }
+
+                    ImageBlock block = blocks[effectiveOffset];
+                    if (block == null) {
+                        break;
+                    }
+                    synchronized (block) {
+                        Bitmap b = block.mBitmap;
+                        if (b == null) {
+                            break;
+                        }
+                        canvas.drawBitmap(b, 0, yPos, mGridViewPaint);
+                        blockCount += 1;
+                    }
+                }
+            }
+        }
+
+        int blockHeight() {
+            return mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight;
+        }
+
+        private class ImageBlock {
+            Drawable mCellOutline;
+            Bitmap mBitmap = Bitmap.createBitmap(getWidth(), blockHeight(),
+                    Bitmap.Config.RGB_565);;
+            Canvas mCanvas = new Canvas(mBitmap);
+            Paint mPaint = new Paint();
+
+            int     mBlockNumber;
+
+            // columns which have been requested to the loader
+            int     mRequestedMask; 
+            
+            // columns which have been completed from the loader
+            int     mCompletedMask;
+            boolean mIsVisible;
+
+            public void dump(StringBuilder line1, StringBuilder line2) {
+                synchronized (ImageBlock.this) {
+                    line2.append(mCompletedMask != 0xF ? 'L' : '_');
+                    line1.append(mIsVisible ? 'V' : ' ');
                 }
             }
 
-            void doDraw(Canvas canvas) {
-                synchronized (ImageBlockManager.this) {
-                    ImageBlockManager.ImageBlock [] blocks = mBlockCache;
-                    int blockCount = 0;
+            ImageBlock() {
+                mPaint.setTextSize(14F);
+                mPaint.setStyle(Paint.Style.FILL);
 
-                    if (blocks[0] == null) {
+                mBlockNumber = -1;
+                mCellOutline = GridViewSpecial.this.getResources()
+                        .getDrawable(android.R.drawable.gallery_thumb);
+            }
+
+            private void recycleBitmaps() {
+                synchronized (ImageBlock.this) {
+                    mBitmap.recycle();
+                    mBitmap = null;
+                }
+            }
+
+            private void cancelExistingRequests() {
+                synchronized (ImageBlock.this) {
+                    for (int i = 0; i < mCurrentSpec.mColumns; i++) {
+                        int mask = (1 << i);
+                        if ((mRequestedMask & mask) != 0) {
+                            int pos =
+                                    (mBlockNumber * mCurrentSpec.mColumns) + i;
+                            if (mLoader.cancel(
+                                    mGallery.mAllImages.getImageAt(pos))) {
+                                mRequestedMask &= ~mask;
+                            }
+                        }
+                    }
+                }
+            }
+
+            private void setStart(final int blockNumber) {
+                synchronized (ImageBlock.this) {
+                    if (blockNumber == mBlockNumber) {
                         return;
                     }
 
-                    final int thisHeight = getHeight();
-                    final int thisWidth  = getWidth();
-                    final int height = blocks[0].mBitmap.getHeight();
-                    final int scrollPos = mScrollY;
+                    cancelExistingRequests();
 
-                    int currentBlock = (scrollPos < 0) ? ((scrollPos-height+1) / height) : (scrollPos / height);
+                    mBlockNumber = blockNumber;
+                    mRequestedMask = 0;
+                    mCompletedMask = 0;
+                    mCanvas.drawColor(0xFF000000);
+                    mPaint.setColor(0xFFDDDDDD);
+                    int imageNumber = blockNumber * mCurrentSpec.mColumns;
+                    int lastImageNumber = mGallery.mAllImages.getCount() - 1;
 
-                    while (true) {
-                        final int yPos = currentBlock * height;
-                        if (yPos >= scrollPos + thisHeight)
+                    int spacing = mCurrentSpec.mCellSpacing;
+                    int leftSpacing = mCurrentSpec.mLeftEdgePadding;
+
+                    final int yPos = spacing;
+
+                    for (int col = 0; col < mCurrentSpec.mColumns; col++) {
+                        if (imageNumber++ >= lastImageNumber) {
                             break;
+                        }
+                        final int xPos = leftSpacing
+                                + (col * (mCurrentSpec.mCellWidth + spacing));
+                        mCanvas.drawRect(xPos, yPos,
+                                xPos + mCurrentSpec.mCellWidth,
+                                yPos + mCurrentSpec.mCellHeight, mPaint);
+                        paintSel(0, xPos, yPos);
+                    }
+                }
+            }
 
-                        if (currentBlock < 0) {
-                            canvas.drawRect(0, yPos, thisWidth, 0, mGridViewPaint);
-                            currentBlock += 1;
+            private boolean setVisibility(boolean isVis) {
+                synchronized (ImageBlock.this) {
+                    boolean retval = mIsVisible != isVis;
+                    mIsVisible = isVis;
+                    return retval;
+                }
+            }
+
+            private int startLoading() {
+                synchronized (ImageBlock.this) {
+                    final int startRow = mBlockNumber;
+                    int count = mGallery.mAllImages.getCount();
+
+                    if (startRow == -1) {
+                        return 0;
+                    }
+
+                    if ((startRow * mCurrentSpec.mColumns) >= count) {
+                        return 0;
+                    }
+
+                    int retVal = 0;
+                    int base = (mBlockNumber * mCurrentSpec.mColumns);
+                    for (int col = 0; col < mCurrentSpec.mColumns; col++) {
+                        if ((mCompletedMask & (1 << col)) != 0) {
                             continue;
                         }
-                        int effectiveOffset = (mBlockCacheStartOffset + (currentBlock++ - mBlockCacheFirstBlockNumber)) % blocks.length;
-                        if (effectiveOffset < 0 || effectiveOffset >= blocks.length) {
-                            break;
-                        }
-
-                        ImageBlock block = blocks[effectiveOffset];
-                        if (block == null) {
-                            break;
-                        }
-                        synchronized (block) {
-                            Bitmap b = block.mBitmap;
-                            if (b == null) {
-                                break;
-                            }
-                            canvas.drawBitmap(b, 0, yPos, mGridViewPaint);
-                            blockCount += 1;
-                        }
-                    }
-                }
-            }
-
-            int blockHeight() {
-                return mCurrentSpec.mCellSpacing + mCurrentSpec.mCellHeight;
-            }
-
-            private class ImageBlock {
-                Drawable mCellOutline;
-                Bitmap mBitmap = Bitmap.createBitmap(getWidth(), blockHeight(),
-                        Bitmap.Config.RGB_565);;
-                Canvas mCanvas = new Canvas(mBitmap);
-                Paint mPaint = new Paint();
-
-                int     mBlockNumber;
-                int     mRequestedMask;   // columns which have been requested to the loader
-                int     mCompletedMask;   // columns which have been completed from the loader
-                boolean mIsVisible;
-
-                public void dump(StringBuilder line1, StringBuilder line2) {
-                    synchronized (ImageBlock.this) {
-//                        Log.v(TAG, "block " + mBlockNumber + " isVis == " + mIsVisible);
-                        line2.append(mCompletedMask != 0xF ? 'L' : '_');
-                        line1.append(mIsVisible ? 'V' : ' ');
-                    }
-                }
-
-                ImageBlock() {
-                    mPaint.setTextSize(14F);
-                    mPaint.setStyle(Paint.Style.FILL);
-
-                    mBlockNumber = -1;
-                    mCellOutline = GridViewSpecial.this.getResources().getDrawable(android.R.drawable.gallery_thumb);
-                }
-
-                private void recycleBitmaps() {
-                    synchronized (ImageBlock.this) {
-                        mBitmap.recycle();
-                        mBitmap = null;
-                    }
-                }
-
-                private void cancelExistingRequests() {
-                    synchronized (ImageBlock.this) {
-                        for (int i = 0; i < mCurrentSpec.mColumns; i++) {
-                            int mask = (1 << i);
-                            if ((mRequestedMask & mask) != 0) {
-                                int pos = (mBlockNumber * mCurrentSpec.mColumns) + i;
-                                if (mLoader.cancel(mGallery.mAllImages.getImageAt(pos))) {
-                                    mRequestedMask &= ~mask;
-                                }
-                            }
-                        }
-                    }
-                }
-
-                private void setStart(final int blockNumber) {
-                    synchronized (ImageBlock.this) {
-                        if (blockNumber == mBlockNumber)
-                            return;
-
-                        cancelExistingRequests();
-
-                        mBlockNumber = blockNumber;
-                        mRequestedMask = 0;
-                        mCompletedMask = 0;
-                        mCanvas.drawColor(0xFF000000);
-                        mPaint.setColor(0xFFDDDDDD);
-                        int imageNumber = blockNumber * mCurrentSpec.mColumns;
-                        int lastImageNumber = mGallery.mAllImages.getCount() - 1;
 
                         int spacing = mCurrentSpec.mCellSpacing;
                         int leftSpacing = mCurrentSpec.mLeftEdgePadding;
-
                         final int yPos = spacing;
+                        final int xPos = leftSpacing
+                                + (col * (mCurrentSpec.mCellWidth + spacing));
 
-                        for (int col = 0; col < mCurrentSpec.mColumns; col++) {
-                            if (imageNumber++ >= lastImageNumber)
-                                break;
-                            final int xPos = leftSpacing + (col * (mCurrentSpec.mCellWidth + spacing));
-                            mCanvas.drawRect(xPos, yPos, xPos+mCurrentSpec.mCellWidth, yPos+mCurrentSpec.mCellHeight, mPaint);
-                            paintSel(0, xPos, yPos);
-                        }
-                    }
-                }
-
-                private boolean setVisibility(boolean isVis) {
-                    synchronized (ImageBlock.this) {
-                        boolean retval = mIsVisible != isVis;
-                        mIsVisible = isVis;
-                        return retval;
-                    }
-                }
-
-                private int startLoading() {
-                    synchronized (ImageBlock.this) {
-                        final int startRow = mBlockNumber;
-                        int count = mGallery.mAllImages.getCount();
-
-                        if (startRow == -1)
-                            return 0;
-
-                        if ((startRow * mCurrentSpec.mColumns) >= count) {
-                            return 0;
+                        int pos = base + col;
+                        if (pos >= count) {
+                            break;
                         }
 
-                        int retVal = 0;
-                        int base = (mBlockNumber * mCurrentSpec.mColumns);
-                        for (int col = 0; col < mCurrentSpec.mColumns; col++) {
-                            if ((mCompletedMask & (1 << col)) != 0) {
-                                continue;
-                            }
+                        IImage image = mGallery.mAllImages.getImageAt(pos);
+                        if (image != null) {
+                            loadImage(base, col, image, xPos, yPos);
+                            retVal += 1;
+                        }
+                    }
+                    return retVal;
 
-                            int spacing = mCurrentSpec.mCellSpacing;
-                            int leftSpacing = mCurrentSpec.mLeftEdgePadding;
-                            final int yPos = spacing;
-                            final int xPos = leftSpacing + (col * (mCurrentSpec.mCellWidth + spacing));
+                }
+            }
 
-                            int pos = base + col;
-                            if (pos >= count)
-                                break;
+            Bitmap resizeBitmap(Bitmap b) {
+                // assume they're both square for now
+                if (b == null || (b.getWidth() == mCurrentSpec.mCellWidth
+                        && b.getHeight() == mCurrentSpec.mCellHeight)) {
+                    return b;
+                }
+                float scale = (float) mCurrentSpec.mCellWidth
+                        / (float) b.getWidth();
+                Matrix m = new Matrix();
+                m.setScale(scale, scale, b.getWidth(), b.getHeight());
+                Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(),
+                        b.getHeight(), m, false);
+                return b2;
+            }
 
-                            IImage image = mGallery.mAllImages.getImageAt(pos);
-                            if (image != null) {
-//                              Log.v(TAG, "calling loadImage " + (base + col));
-                                loadImage(base, col, image, xPos, yPos);
-                                retVal += 1;
+            private void drawBitmap(IImage image, int base, int baseOffset,
+                    Bitmap b, int xPos, int yPos) {
+                mCanvas.setBitmap(mBitmap);
+                if (b != null) {
+                    // if the image is close to the target size then crop,
+                    // otherwise scale both the bitmap and the view should be
+                    // square but I suppose that could change in the future.
+                    int w = mCurrentSpec.mCellWidth;
+                    int h = mCurrentSpec.mCellHeight;
+
+                    int bw = b.getWidth();
+                    int bh = b.getHeight();
+
+                    int deltaW = bw - w;
+                    int deltaH = bh - h;
+
+                    if (deltaW < 10 && deltaH < 10) {
+                        int halfDeltaW = deltaW / 2;
+                        int halfDeltaH = deltaH / 2;
+                        android.graphics.Rect src =
+                                new android.graphics.Rect(0 + halfDeltaW,
+                                0 + halfDeltaH, bw - halfDeltaW,
+                                bh - halfDeltaH);
+                        android.graphics.Rect dst =
+                                new android.graphics.Rect(xPos, yPos,
+                                xPos + w, yPos + h);
+                        if (src.width() != dst.width()
+                                || src.height() != dst.height()) {
+                            if (Config.LOGV){
+                                Log.v(TAG, "nope... width doesn't match "
+                                        + src.width() + " " + dst.width());
+                                Log.v(TAG, "nope... height doesn't match "
+                                        + src.height() + " " + dst.height());
                             }
                         }
-                        return retVal;
-
-                    }
-                }
-
-                Bitmap resizeBitmap(Bitmap b) {
-                    // assume they're both square for now
-                    if (b == null || (b.getWidth() == mCurrentSpec.mCellWidth && b.getHeight() == mCurrentSpec.mCellHeight)) {
-                        return b;
-                    }
-                    float scale = (float) mCurrentSpec.mCellWidth / (float)b.getWidth();
-                    Matrix m = new Matrix();
-                    m.setScale(scale, scale, b.getWidth(), b.getHeight());
-                    Bitmap b2 = Bitmap.createBitmap(b, 0, 0, b.getWidth(), b.getHeight(), m, false);
-                    return b2;
-                }
-
-                private void drawBitmap(IImage image, int base, int baseOffset, Bitmap b, int xPos, int yPos) {
-                    mCanvas.setBitmap(mBitmap);
-                    if (b != null) {
-                        // if the image is close to the target size then crop, otherwise scale
-                        // both the bitmap and the view should be square but I suppose that could
-                        // change in the future.
-                        int w = mCurrentSpec.mCellWidth;
-                        int h = mCurrentSpec.mCellHeight;
-
-                        int bw = b.getWidth();
-                        int bh = b.getHeight();
-
-                        int deltaW = bw - w;
-                        int deltaH = bh - h;
-
-                        if (deltaW < 10 && deltaH < 10) {
-                            int halfDeltaW = deltaW / 2;
-                            int halfDeltaH = deltaH / 2;
-                            android.graphics.Rect src = new android.graphics.Rect(0+halfDeltaW, 0+halfDeltaH, bw-halfDeltaW, bh-halfDeltaH);
-                            android.graphics.Rect dst = new android.graphics.Rect(xPos, yPos, xPos+w, yPos+h);
-                            if (src.width() != dst.width() || src.height() != dst.height()) {
-                                if (Config.LOGV){
-                                    Log.v(TAG, "nope... width doesn't match " + src.width() + " " + dst.width());
-                                    Log.v(TAG, "nope... height doesn't match " + src.height() + " " + dst.height());
-                                }
-                            }
-                            mCanvas.drawBitmap(b, src, dst, mPaint);
-                        } else {
-                            android.graphics.Rect src = new android.graphics.Rect(0, 0, bw, bh);
-                            android.graphics.Rect dst = new android.graphics.Rect(xPos, yPos, xPos+w, yPos+h);
-                            mCanvas.drawBitmap(b, src, dst, mPaint);
-                        }
+                        mCanvas.drawBitmap(b, src, dst, mPaint);
                     } else {
-                        // If the thumbnail cannot be drawn, put up an error icon instead
-                        Bitmap error = mImageBlockManager.getErrorBitmap(image);
-                        int width = error.getWidth();
-                        int height = error.getHeight();
-                        Rect source = new Rect(0, 0, width, height);
-                        int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos;
-                        int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos;
-                        Rect dest = new Rect(left, top, left + width, top + height);
-                        mCanvas.drawBitmap(error, source, dest, mPaint);
+                        android.graphics.Rect src =
+                                new android.graphics.Rect(0, 0, bw, bh);
+                        android.graphics.Rect dst =
+                                new android.graphics.Rect(xPos, yPos, xPos + w,
+                                yPos + h);
+                        mCanvas.drawBitmap(b, src, dst, mPaint);
                     }
-                    if (ImageManager.isVideo(image)) {
-                        Drawable overlay = null;
-                        long size = MenuHelper.getImageFileSize(image);
-                        if (size >= 0 && size <= mVideoSizeLimit) {
-                            if (mVideoOverlay == null) {
-                                mVideoOverlay = getResources().getDrawable(
-                                        R.drawable.ic_gallery_video_overlay);
-                            }
-                            overlay = mVideoOverlay;
-                        } else {
-                            if (mVideoMmsErrorOverlay == null) {
-                                mVideoMmsErrorOverlay = getResources().getDrawable(
-                                        R.drawable.ic_error_mms_video_overlay);
-                            }
-                            overlay = mVideoMmsErrorOverlay;
-                            Paint paint = new Paint();
-                            paint.setARGB(0x80, 0x00, 0x00, 0x00);
-                            mCanvas.drawRect(xPos, yPos, xPos + mCurrentSpec.mCellWidth,
-                                    yPos + mCurrentSpec.mCellHeight, paint);
-                        }
-                        int width = overlay.getIntrinsicWidth();
-                        int height = overlay.getIntrinsicHeight();
-                        int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos;
-                        int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos;
-                        Rect newBounds = new Rect(left, top, left + width, top + height);
-                        overlay.setBounds(newBounds);
-                        overlay.draw(mCanvas);
-                    }
-                    paintSel(base + baseOffset, xPos, yPos);
+                } else {
+                    // If the thumbnail cannot be drawn, put up an error icon
+                    // instead
+                    Bitmap error = mImageBlockManager.getErrorBitmap(image);
+                    int width = error.getWidth();
+                    int height = error.getHeight();
+                    Rect source = new Rect(0, 0, width, height);
+                    int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos;
+                    int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos;
+                    Rect dest = new Rect(left, top, left + width, top + height);
+                    mCanvas.drawBitmap(error, source, dest, mPaint);
                 }
-
-                private void repaintSelection() {
-                    int count = mGallery.mAllImages.getCount();
-                    int startPos = mBlockNumber * mCurrentSpec.mColumns;
-                    synchronized (ImageBlock.this) {
-                        for (int i = 0; i < mCurrentSpec.mColumns; i++) {
-                            int pos = startPos + i;
-
-                            if (pos >= count)
-                                break;
-
-                            int row = 0; // i / mCurrentSpec.mColumns;
-                            int col = i - (row * mCurrentSpec.mColumns);
-
-                            // this is duplicated from getOrKick (TODO: don't duplicate this code)
-                            int spacing = mCurrentSpec.mCellSpacing;
-                            int leftSpacing = mCurrentSpec.mLeftEdgePadding;
-                            final int yPos = spacing + (row * (mCurrentSpec.mCellHeight + spacing));
-                            final int xPos = leftSpacing + (col * (mCurrentSpec.mCellWidth + spacing));
-
-                            paintSel(pos, xPos, yPos);
+                if (ImageManager.isVideo(image)) {
+                    Drawable overlay = null;
+                    long size = MenuHelper.getImageFileSize(image);
+                    if (size >= 0 && size <= mVideoSizeLimit) {
+                        if (mVideoOverlay == null) {
+                            mVideoOverlay = getResources().getDrawable(
+                                    R.drawable.ic_gallery_video_overlay);
                         }
-                    }
-                }
-
-                private void paintSel(int pos, int xPos, int yPos) {
-                    int[] stateSet = EMPTY_STATE_SET;
-                    if (pos == mCurrentSelection && mShowSelection) {
-                        if (mCurrentSelectionPressed) {
-                            stateSet = PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
-                        } else {
-                            stateSet = ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
+                        overlay = mVideoOverlay;
+                    } else {
+                        if (mVideoMmsErrorOverlay == null) {
+                            mVideoMmsErrorOverlay = getResources().getDrawable(
+                                    R.drawable.ic_error_mms_video_overlay);
                         }
+                        overlay = mVideoMmsErrorOverlay;
+                        Paint paint = new Paint();
+                        paint.setARGB(0x80, 0x00, 0x00, 0x00);
+                        mCanvas.drawRect(xPos, yPos,
+                                xPos + mCurrentSpec.mCellWidth,
+                                yPos + mCurrentSpec.mCellHeight, paint);
                     }
-
-                    mCellOutline.setState(stateSet);
-                    mCanvas.setBitmap(mBitmap);
-                    mCellOutline.setBounds(xPos, yPos, xPos+mCurrentSpec.mCellWidth, yPos+mCurrentSpec.mCellHeight);
-                    mCellOutline.draw(mCanvas);
+                    int width = overlay.getIntrinsicWidth();
+                    int height = overlay.getIntrinsicHeight();
+                    int left = (mCurrentSpec.mCellWidth - width) / 2 + xPos;
+                    int top = (mCurrentSpec.mCellHeight - height) / 2 + yPos;
+                    Rect newBounds =
+                            new Rect(left, top, left + width, top + height);
+                    overlay.setBounds(newBounds);
+                    overlay.draw(mCanvas);
                 }
+                paintSel(base + baseOffset, xPos, yPos);
+            }
 
-                private void loadImage(
-                        final int base,
-                        final int baseOffset,
-                        final IImage image,
-                        final int xPos,
-                        final int yPos) {
-                    synchronized (ImageBlock.this) {
-                        final int startBlock = mBlockNumber;
-                        final int pos = base + baseOffset;
-                        final ImageLoader.LoadedCallback r = new ImageLoader.LoadedCallback() {
-                            public void run(Bitmap b) {
-                                boolean more = false;
-                                synchronized (ImageBlock.this) {
-                                    if (startBlock != mBlockNumber) {
-//                                      Log.v(TAG, "wanted block " + mBlockNumber + " but got " + startBlock);
-                                        return;
-                                    }
+            private void repaintSelection() {
+                int count = mGallery.mAllImages.getCount();
+                int startPos = mBlockNumber * mCurrentSpec.mColumns;
+                synchronized (ImageBlock.this) {
+                    for (int i = 0; i < mCurrentSpec.mColumns; i++) {
+                        int pos = startPos + i;
 
-                                    if (mBitmap == null) {
-                                        return;
-                                    }
+                        if (pos >= count) {
+                            break;
+                        }
 
-                                    drawBitmap(image, base, baseOffset, b, xPos, yPos);
+                        int row = 0; // i / mCurrentSpec.mColumns;
+                        int col = i - (row * mCurrentSpec.mColumns);
 
-                                    int mask = (1 << baseOffset);
-                                    mRequestedMask &= ~mask;
-                                    mCompletedMask |= mask;
+                        // this is duplicated from getOrKick 
+                        // (TODO: don't duplicate this code)
+                        int spacing = mCurrentSpec.mCellSpacing;
+                        int leftSpacing = mCurrentSpec.mLeftEdgePadding;
+                        final int yPos = spacing
+                                + (row * (mCurrentSpec.mCellHeight + spacing));
+                        final int xPos = leftSpacing
+                                + (col * (mCurrentSpec.mCellWidth + spacing));
 
-                                 // Log.v(TAG, "for " + mBlockNumber + " mRequestedMask is " + String.format("%x", mRequestedMask) + " and mCompletedMask is " + String.format("%x", mCompletedMask));
-
-                                    if (mRequestedMask == 0) {
-                                        if (mIsVisible) {
-                                            postInvalidate();
-                                        }
-                                        more = true;
-                                    }
-                                }
-                                if (b != null)
-                                    b.recycle();
-
-                                if (more) {
-                                    synchronized (ImageBlockManager.this) {
-                                        ImageBlockManager.this.notify();
-                                        mWorkCounter += 1;
-                                    }
-                                }
-                                if (sDump)
-                                    ImageBlockManager.this.dump();
-                            }
-                        };
-                        mRequestedMask |= (1 << baseOffset);
-                        mLoader.getBitmap(image, pos, r, mIsVisible, false);
+                        paintSel(pos, xPos, yPos);
                     }
                 }
             }
+
+            private void paintSel(int pos, int xPos, int yPos) {
+                int[] stateSet = EMPTY_STATE_SET;
+                if (pos == mCurrentSelection && mShowSelection) {
+                    if (mCurrentSelectionPressed) {
+                        stateSet = PRESSED_ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
+                    } else {
+                        stateSet = ENABLED_FOCUSED_SELECTED_WINDOW_FOCUSED_STATE_SET;
+                    }
+                }
+
+                mCellOutline.setState(stateSet);
+                mCanvas.setBitmap(mBitmap);
+                mCellOutline.setBounds(xPos, yPos,
+                        xPos + mCurrentSpec.mCellWidth,
+                        yPos + mCurrentSpec.mCellHeight);
+                mCellOutline.draw(mCanvas);
+            }
+
+            private void loadImage(
+                    final int base,
+                    final int baseOffset,
+                    final IImage image,
+                    final int xPos,
+                    final int yPos) {
+                synchronized (ImageBlock.this) {
+                    final int startBlock = mBlockNumber;
+                    final int pos = base + baseOffset;
+                    final ImageLoader.LoadedCallback r =
+                            new ImageLoader.LoadedCallback() {
+                        public void run(Bitmap b) {
+                            boolean more = false;
+                            synchronized (ImageBlock.this) {
+                                if (startBlock != mBlockNumber) {
+                                    return;
+                                }
+
+                                if (mBitmap == null) {
+                                    return;
+                                }
+
+                                drawBitmap(image, base, baseOffset, b, xPos,
+                                        yPos);
+
+                                int mask = (1 << baseOffset);
+                                mRequestedMask &= ~mask;
+                                mCompletedMask |= mask;
+
+                                if (mRequestedMask == 0) {
+                                    if (mIsVisible) {
+                                        postInvalidate();
+                                    }
+                                    more = true;
+                                }
+                            }
+                            if (b != null) {
+                                b.recycle();
+                            }
+
+                            if (more) {
+                                synchronized (ImageBlockManager.this) {
+                                    ImageBlockManager.this.notify();
+                                    mWorkCounter += 1;
+                                }
+                            }
+                            if (DUMP) {
+                                ImageBlockManager.this.dump();
+                            }
+                        }
+                    };
+                    mRequestedMask |= (1 << baseOffset);
+                    mLoader.getBitmap(image, pos, r, mIsVisible, false);
+                }
+            }
+        }
+    }
+
+    public void init(Handler handler) {
+        mHandler = handler;
+    }
+
+    public void onDraw(Canvas canvas) {
+        super.onDraw(canvas);
+        if (false) {
+            canvas.drawRect(0, 0, getWidth(), getHeight(), mGridViewPaint);
+            if (Config.LOGV) {
+                Log.v(TAG, "painting background w/h " + getWidth()
+                        + " / " + getHeight());
+            }
+            return;
         }
 
-        public void init(Handler handler) {
-            mHandler = handler;
+        if (mImageBlockManager != null) {
+            mImageBlockManager.doDraw(canvas);
+            mImageBlockManager.moveDataWindow(mDirectionBiasDown, false);
         }
+    }
 
-        public void onDraw(Canvas canvas) {
-            super.onDraw(canvas);
-            if (false) {
-                canvas.drawRect(0, 0, getWidth(), getHeight(), mGridViewPaint);
-                if (Config.LOGV)
-                    Log.v(TAG, "painting background w/h " + getWidth() + " / " + getHeight());
+    @Override
+    public void computeScroll() {
+        if (mScroller != null) {
+            boolean more = mScroller.computeScrollOffset();
+            scrollTo(0, (int) mScroller.getCurrY());
+            if (more) {
+                postInvalidate();  // So we draw again
+            } else {
+                mScroller = null;
+            }
+        } else {
+            super.computeScroll();
+        }
+    }
+
+    android.graphics.Rect getRectForPosition(int pos) {
+        int row = pos / mCurrentSpec.mColumns;
+        int col = pos - (row * mCurrentSpec.mColumns);
+
+        int left = mCurrentSpec.mLeftEdgePadding
+                + (col * mCurrentSpec.mCellWidth)
+                + (Math.max(0, col - 1) * mCurrentSpec.mCellSpacing);
+        int top  = (row * mCurrentSpec.mCellHeight)
+                + (row * mCurrentSpec.mCellSpacing);
+
+        return new android.graphics.Rect(left, top,
+                left + mCurrentSpec.mCellWidth + mCurrentSpec.mCellWidth,
+                top + mCurrentSpec.mCellHeight + mCurrentSpec.mCellSpacing);
+    }
+
+    int computeSelectedIndex(android.view.MotionEvent ev) {
+        int spacing = mCurrentSpec.mCellSpacing;
+        int leftSpacing = mCurrentSpec.mLeftEdgePadding;
+
+        int x = (int) ev.getX();
+        int y = (int) ev.getY();
+        int row = (mScrollY + y - spacing)
+                / (mCurrentSpec.mCellHeight + spacing);
+        int col = Math.min(mCurrentSpec.mColumns - 1,
+                (x - leftSpacing) / (mCurrentSpec.mCellWidth + spacing));
+        return (row * mCurrentSpec.mColumns) + col;
+    }
+
+    @Override
+    public boolean onTouchEvent(android.view.MotionEvent ev) {
+        if (!mGallery.canHandleEvent()) {
+            return false;
+        }
+        
+        mGestureDetector.onTouchEvent(ev);
+        return true;
+    }
+
+    void onSelect(int index) {
+        if (index >= 0 && index < mGallery.mAllImages.getCount()) {
+            IImage img = mGallery.mAllImages.getImageAt(index);
+            if (img == null) {
                 return;
             }
 
-            if (mImageBlockManager != null) {
-                mImageBlockManager.doDraw(canvas);
-                mImageBlockManager.moveDataWindow(mDirectionBiasDown, false);
-            }
-        }
-
-        @Override
-        public void computeScroll() {
-            if (mScroller != null) {
-                boolean more = mScroller.computeScrollOffset();
-                scrollTo(0, (int)mScroller.getCurrY());
-                if (more) {
-                    postInvalidate();  // So we draw again
-                } else {
-                    mScroller = null;
-                }
+            if (mGallery.isPickIntent()) {
+                mGallery.launchCropperOrFinish(img);
             } else {
-                super.computeScroll();
-            }
-        }
-
-        private android.graphics.Rect getRectForPosition(int pos) {
-            int row = pos / mCurrentSpec.mColumns;
-            int col = pos - (row * mCurrentSpec.mColumns);
-
-            int left = mCurrentSpec.mLeftEdgePadding + (col * mCurrentSpec.mCellWidth) + (Math.max(0, col-1) * mCurrentSpec.mCellSpacing);
-            int top  = (row * mCurrentSpec.mCellHeight) + (row * mCurrentSpec.mCellSpacing);
-
-            return new android.graphics.Rect(left, top, left + mCurrentSpec.mCellWidth + mCurrentSpec.mCellWidth, top + mCurrentSpec.mCellHeight + mCurrentSpec.mCellSpacing);
-        }
-
-        int computeSelectedIndex(android.view.MotionEvent ev) {
-            int spacing = mCurrentSpec.mCellSpacing;
-            int leftSpacing = mCurrentSpec.mLeftEdgePadding;
-
-            int x = (int) ev.getX();
-            int y = (int) ev.getY();
-            int row = (mScrollY + y - spacing) / (mCurrentSpec.mCellHeight + spacing);
-            int col = Math.min(mCurrentSpec.mColumns - 1, (x - leftSpacing) / (mCurrentSpec.mCellWidth + spacing));
-            return (row * mCurrentSpec.mColumns) + col;
-        }
-
-        @Override
-        public boolean onTouchEvent(android.view.MotionEvent ev) {
-            if (!mGallery.canHandleEvent())  return false;
-            
-            mGestureDetector.onTouchEvent(ev);
-            return true;
-        }
-
-        private void onSelect(int index) {
-            if (index >= 0 && index < mGallery.mAllImages.getCount()) {
-                IImage img = mGallery.mAllImages.getImageAt(index);
-                if (img == null)
-                    return;
-
-                if (mGallery.isPickIntent()) {
-                    mGallery.launchCropperOrFinish(img);
-                } else {
-                    Uri targetUri = img.fullSizeImageUri();
-                    Uri thisUri = mGallery.getIntent().getData();
-                    if (thisUri != null) {
-                        String bucket = thisUri.getQueryParameter("bucketId");
-                        if (bucket != null) {
-                            targetUri = targetUri.buildUpon().appendQueryParameter("bucketId", bucket).build();
-                        }
+                Uri targetUri = img.fullSizeImageUri();
+                Uri thisUri = mGallery.getIntent().getData();
+                if (thisUri != null) {
+                    String bucket = thisUri.getQueryParameter("bucketId");
+                    if (bucket != null) {
+                        targetUri = targetUri.buildUpon()
+                                .appendQueryParameter("bucketId", bucket)
+                                .build();
                     }
-                    Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
+                }
+                Intent intent = new Intent(Intent.ACTION_VIEW, targetUri);
 
-                    if (img instanceof VideoObject) {
-                        intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
-                                ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
-                    }
+                if (img instanceof VideoObject) {
+                    intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
+                            ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+                }
 
-                    try {
-                        mContext.startActivity(intent);
-                    } catch (Exception ex) {
-                        // sdcard removal??
-                    }
+                try {
+                    mContext.startActivity(intent);
+                } catch (Exception ex) {
+                    // sdcard removal??
                 }
             }
         }
+    }
 
-        @Override
-        public void scrollBy(int x, int y) {
-            scrollTo(x, mScrollY + y);
+    @Override
+    public void scrollBy(int x, int y) {
+        scrollTo(x, mScrollY + y);
+    }
+
+    Toast mDateLocationToast;
+    int [] mDateRange = new int[2];
+
+    private String month(int month) {
+        String text = "";
+        switch (month) {
+            case 0:  text = "January";   break;
+            case 1:  text = "February";  break;
+            case 2:  text = "March";     break;
+            case 3:  text = "April";     break;
+            case 4:  text = "May";       break;
+            case 5:  text = "June";      break;
+            case 6:  text = "July";      break;
+            case 7:  text = "August";    break;
+            case 8:  text = "September"; break;
+            case 9:  text = "October";   break;
+            case 10: text = "November";  break;
+            case 11: text = "December";  break;
         }
+        return text;
+    }
 
-        Toast mDateLocationToast;
-        int [] mDateRange = new int[2];
-
-        private String month(int month) {
-            String text = "";
-            switch (month) {
-                case 0:  text = "January";   break;
-                case 1:  text = "February";  break;
-                case 2:  text = "March";     break;
-                case 3:  text = "April";     break;
-                case 4:  text = "May";       break;
-                case 5:  text = "June";      break;
-                case 6:  text = "July";      break;
-                case 7:  text = "August";    break;
-                case 8:  text = "September"; break;
-                case 9:  text = "October";   break;
-                case 10: text = "November";  break;
-                case 11: text = "December";  break;
+    Runnable mToastRunnable = new Runnable() {
+        public void run() {
+            if (mDateLocationToast != null) {
+                mDateLocationToast.cancel();
+                mDateLocationToast = null;
             }
-            return text;
-        }
 
-        Runnable mToastRunnable = new Runnable() {
-            public void run() {
-                if (mDateLocationToast != null) {
-                    mDateLocationToast.cancel();
-                    mDateLocationToast = null;
-                }
-
-                int count = mGallery.mAllImages.getCount();
-                if (count == 0)
-                    return;
-
-                GridViewSpecial.this.mImageBlockManager.getVisibleRange(mDateRange);
-
-                IImage firstImage = mGallery.mAllImages.getImageAt(mDateRange[0]);
-                int lastOffset = Math.min(count-1, mDateRange[1]);
-                IImage lastImage = mGallery.mAllImages.getImageAt(lastOffset);
-
-                GregorianCalendar dateStart = new GregorianCalendar();
-                GregorianCalendar dateEnd   = new GregorianCalendar();
-
-                dateStart.setTimeInMillis(firstImage.getDateTaken());
-                dateEnd.setTimeInMillis(lastImage.getDateTaken());
-
-                String text1 = month(dateStart.get(Calendar.MONTH)) + " " + dateStart.get(Calendar.YEAR);
-                String text2 = month(dateEnd  .get(Calendar.MONTH)) + " " + dateEnd  .get(Calendar.YEAR);
-
-                String text = text1;
-                if (!text2.equals(text1))
-                    text = text + " : " + text2;
-
-                mDateLocationToast = Toast.makeText(mContext, text, Toast.LENGTH_LONG);
-                mDateLocationToast.show();
+            int count = mGallery.mAllImages.getCount();
+            if (count == 0) {
+                return;
             }
-        };
 
-        @Override
-        public void scrollTo(int x, int y) {
-            y = Math.min(mMaxScrollY, y);
-            y = Math.max(mMinScrollY, y);
-            if (y > mScrollY)
-                mDirectionBiasDown = true;
-            else if (y < mScrollY)
-                mDirectionBiasDown = false;
-            super.scrollTo(x, y);
+            GridViewSpecial.this.mImageBlockManager.getVisibleRange(mDateRange);
+
+            IImage firstImage = mGallery.mAllImages.getImageAt(mDateRange[0]);
+            int lastOffset = Math.min(count - 1, mDateRange[1]);
+            IImage lastImage = mGallery.mAllImages.getImageAt(lastOffset);
+
+            GregorianCalendar dateStart = new GregorianCalendar();
+            GregorianCalendar dateEnd   = new GregorianCalendar();
+
+            dateStart.setTimeInMillis(firstImage.getDateTaken());
+            dateEnd.setTimeInMillis(lastImage.getDateTaken());
+
+            String text1 = month(dateStart.get(Calendar.MONTH)) + " "
+                    + dateStart.get(Calendar.YEAR);
+            String text2 = month(dateEnd.get(Calendar.MONTH)) + " "
+                    + dateEnd.get(Calendar.YEAR);
+
+            String text = text1;
+            if (!text2.equals(text1)) {
+                text = text + " : " + text2;
+            }
+
+            mDateLocationToast = Toast.makeText(mContext, text,
+                    Toast.LENGTH_LONG);
+            mDateLocationToast.show();
         }
+    };
+
+    @Override
+    public void scrollTo(int x, int y) {
+        y = Math.min(mMaxScrollY, y);
+        y = Math.max(mMinScrollY, y);
+        if (y > mScrollY) {
+            mDirectionBiasDown = true;
+        } else if (y < mScrollY) {
+            mDirectionBiasDown = false;
+        }
+        super.scrollTo(x, y);
     }
 }
diff --git a/src/com/android/camera/MenuHelper.java b/src/com/android/camera/MenuHelper.java
index 7e9116a..b572232 100644
--- a/src/com/android/camera/MenuHelper.java
+++ b/src/com/android/camera/MenuHelper.java
@@ -18,9 +18,6 @@
 
 import com.android.camera.gallery.IImage;
 
-import java.io.Closeable;
-import java.util.ArrayList;
-
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.content.ActivityNotFoundException;
@@ -39,51 +36,55 @@
 import android.util.Log;
 import android.view.Menu;
 import android.view.MenuItem;
+import android.view.MenuItem.OnMenuItemClickListener;
 import android.view.SubMenu;
 import android.view.View;
-import android.view.MenuItem.OnMenuItemClickListener;
 import android.widget.ImageView;
 import android.widget.TextView;
 import android.widget.Toast;
 
+import java.io.Closeable;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Date;
 
 public class MenuHelper {
-    static private final String TAG = "MenuHelper";
+    private static final String TAG = "MenuHelper";
 
-    static public final int GENERIC_ITEM      = 1;
-    static public final int IMAGE_SAVING_ITEM = 2;
-    static public final int VIDEO_SAVING_ITEM = 3;
-    static public final int IMAGE_MODE_ITEM   = 4;
-    static public final int VIDEO_MODE_ITEM   = 5;
-    static public final int MENU_ITEM_MAX     = 5;
+    public static final int GENERIC_ITEM      = 1;
+    public static final int IMAGE_SAVING_ITEM = 2;
+    public static final int VIDEO_SAVING_ITEM = 3;
+    public static final int IMAGE_MODE_ITEM   = 4;
+    public static final int VIDEO_MODE_ITEM   = 5;
+    public static final int MENU_ITEM_MAX     = 5;
 
-    static public final int INCLUDE_ALL           = 0xFFFFFFFF;
-    static public final int INCLUDE_VIEWPLAY_MENU = (1 << 0);
-    static public final int INCLUDE_SHARE_MENU    = (1 << 1);
-    static public final int INCLUDE_SET_MENU      = (1 << 2);
-    static public final int INCLUDE_CROP_MENU     = (1 << 3);
-    static public final int INCLUDE_DELETE_MENU   = (1 << 4);
-    static public final int INCLUDE_ROTATE_MENU   = (1 << 5);
-    static public final int INCLUDE_DETAILS_MENU  = (1 << 6);
+    public static final int INCLUDE_ALL           = 0xFFFFFFFF;
+    public static final int INCLUDE_VIEWPLAY_MENU = (1 << 0);
+    public static final int INCLUDE_SHARE_MENU    = (1 << 1);
+    public static final int INCLUDE_SET_MENU      = (1 << 2);
+    public static final int INCLUDE_CROP_MENU     = (1 << 3);
+    public static final int INCLUDE_DELETE_MENU   = (1 << 4);
+    public static final int INCLUDE_ROTATE_MENU   = (1 << 5);
+    public static final int INCLUDE_DETAILS_MENU  = (1 << 6);
 
-    static public final int MENU_SWITCH_CAMERA_MODE = 0;
-    static public final int MENU_CAPTURE_PICTURE = 1;
-    static public final int MENU_CAPTURE_VIDEO = 2;
-    static public final int MENU_IMAGE_SHARE = 10;
-    static public final int MENU_IMAGE_SET = 14;
-    static public final int MENU_IMAGE_SET_WALLPAPER = 15;
-    static public final int MENU_IMAGE_SET_CONTACT = 16;
-    static public final int MENU_IMAGE_SET_MYFAVE = 17;
-    static public final int MENU_IMAGE_CROP = 18;
-    static public final int MENU_IMAGE_ROTATE = 19;
-    static public final int MENU_IMAGE_ROTATE_LEFT = 20;
-    static public final int MENU_IMAGE_ROTATE_RIGHT = 21;
-    static public final int MENU_IMAGE_TOSS = 22;
-    static public final int MENU_VIDEO_PLAY = 23;
-    static public final int MENU_VIDEO_SHARE = 24;
-    static public final int MENU_VIDEO_TOSS = 27;
+    public static final int MENU_SWITCH_CAMERA_MODE = 0;
+    public static final int MENU_CAPTURE_PICTURE = 1;
+    public static final int MENU_CAPTURE_VIDEO = 2;
+    public static final int MENU_IMAGE_SHARE = 10;
+    public static final int MENU_IMAGE_SET = 14;
+    public static final int MENU_IMAGE_SET_WALLPAPER = 15;
+    public static final int MENU_IMAGE_SET_CONTACT = 16;
+    public static final int MENU_IMAGE_SET_MYFAVE = 17;
+    public static final int MENU_IMAGE_CROP = 18;
+    public static final int MENU_IMAGE_ROTATE = 19;
+    public static final int MENU_IMAGE_ROTATE_LEFT = 20;
+    public static final int MENU_IMAGE_ROTATE_RIGHT = 21;
+    public static final int MENU_IMAGE_TOSS = 22;
+    public static final int MENU_VIDEO_PLAY = 23;
+    public static final int MENU_VIDEO_SHARE = 24;
+    public static final int MENU_VIDEO_TOSS = 27;
 
-    static private final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
+    private static final long SHARE_FILE_LENGTH_LIMIT = 3L * 1024L * 1024L;
 
     public static final int NO_STORAGE_ERROR = -1;
     public static final int CANNOT_STAT_ERROR = -2;
@@ -142,6 +143,309 @@
         }
     }
 
+    private static boolean onDetailsClicked(MenuInvoker onInvoke,
+                                           final Activity activity,
+                                           final boolean isImage) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (image == null) {
+                    return;
+                }
+
+                AlertDialog.Builder builder = new AlertDialog.Builder(activity);
+
+                final View d = View.inflate(activity, R.layout.detailsview,
+                        null);
+
+                ImageView imageView = (ImageView) d.findViewById(
+                        R.id.details_thumbnail_image);
+                imageView.setImageBitmap(image.miniThumbBitmap());
+
+                TextView textView = (TextView) d.findViewById(
+                        R.id.details_image_title);
+                textView.setText(image.getDisplayName());
+
+                long length = getImageFileSize(image);
+                String lengthString = lengthString = length < 0 ? ""
+                        : android.text.format.Formatter.formatFileSize(
+                        activity, length);
+                ((TextView) d
+                    .findViewById(R.id.details_file_size_value))
+                    .setText(lengthString);
+
+                int dimensionWidth = 0;
+                int dimensionHeight = 0;
+                if (isImage) {
+                    dimensionWidth = image.getWidth();
+                    dimensionHeight = image.getHeight();
+                    d.findViewById(R.id.details_duration_row)
+                            .setVisibility(View.GONE);
+                    d.findViewById(R.id.details_frame_rate_row)
+                            .setVisibility(View.GONE);
+                    d.findViewById(R.id.details_bit_rate_row)
+                            .setVisibility(View.GONE);
+                    d.findViewById(R.id.details_format_row)
+                            .setVisibility(View.GONE);
+                    d.findViewById(R.id.details_codec_row)
+                            .setVisibility(View.GONE);
+                } else {
+                    MediaMetadataRetriever retriever
+                            = new MediaMetadataRetriever();
+                    try {
+                        retriever.setMode(MediaMetadataRetriever
+                                .MODE_GET_METADATA_ONLY);
+                        retriever.setDataSource(image.getDataPath());
+                        try {
+                            dimensionWidth = Integer.parseInt(
+                                    retriever.extractMetadata(
+                                    MediaMetadataRetriever
+                                    .METADATA_KEY_VIDEO_WIDTH));
+                            dimensionHeight = Integer.parseInt(
+                                    retriever.extractMetadata(
+                                    MediaMetadataRetriever
+                                    .METADATA_KEY_VIDEO_HEIGHT));
+                        } catch (NumberFormatException e) {
+                            dimensionWidth = 0;
+                            dimensionHeight = 0;
+                        }
+
+                        try {
+                            int durationMs = Integer.parseInt(
+                                    retriever.extractMetadata(
+                                    MediaMetadataRetriever
+                                    .METADATA_KEY_DURATION));
+                            String durationValue = formatDuration(
+                                    activity, durationMs);
+                            ((TextView) d.findViewById(
+                                R.id.details_duration_value))
+                                .setText(durationValue);
+                        } catch (NumberFormatException e) {
+                            d.findViewById(
+                                    R.id.details_frame_rate_row)
+                                    .setVisibility(View.GONE);
+                        }
+
+                        try {
+                            String frameRate = String.format(
+                                    activity.getString(R.string.details_fps),
+                                    Integer.parseInt(
+                                            retriever.extractMetadata(
+                                            MediaMetadataRetriever
+                                            .METADATA_KEY_FRAME_RATE)));
+                            ((TextView) d.findViewById(
+                                R.id.details_frame_rate_value))
+                                .setText(frameRate);
+                        } catch (NumberFormatException e) {
+                            d.findViewById(
+                                    R.id.details_frame_rate_row)
+                                    .setVisibility(View.GONE);
+                        }
+
+                        try {
+                            long bitRate = Long.parseLong(
+                                    retriever.extractMetadata(
+                                    MediaMetadataRetriever
+                                    .METADATA_KEY_BIT_RATE));
+                            String bps;
+                            if (bitRate < 1000000) {
+                                bps = String.format(
+                                        activity.getString(
+                                        R.string.details_kbps),
+                                        bitRate / 1000);
+                            } else {
+                                bps = String.format(
+                                        activity.getString(
+                                        R.string.details_mbps),
+                                        ((double) bitRate) / 1000000.0);
+                            }
+                            ((TextView) d.findViewById(
+                                    R.id.details_bit_rate_value))
+                                    .setText(bps);
+                        } catch (NumberFormatException e) {
+                            d.findViewById(R.id.details_bit_rate_row)
+                                    .setVisibility(View.GONE);
+                        }
+
+                        String format = retriever.extractMetadata(
+                                MediaMetadataRetriever
+                                .METADATA_KEY_VIDEO_FORMAT);
+                        ((TextView) d.findViewById(
+                                R.id.details_format_value))
+                                .setText(format);
+
+                        String codec = retriever.extractMetadata(
+                                MediaMetadataRetriever.METADATA_KEY_CODEC);
+
+                        if (codec == null) {
+                            d.findViewById(R.id.details_codec_row).
+                                    setVisibility(View.GONE);
+                        } else {
+                            ((TextView) d.findViewById(
+                                    R.id.details_codec_value))
+                                    .setText(codec);
+                        }
+                    } catch (RuntimeException ex) {
+                        // Assume this is a corrupt video file.
+                    } finally {
+                        try {
+                            retriever.release();
+                        } catch (RuntimeException ex) {
+                            // Ignore failures while cleaning up.
+                        }
+                    }
+                }
+
+                String dimensionsString = String.format(
+                        activity.getString(R.string.details_dimension_x),
+                        dimensionWidth, dimensionHeight);
+                ((TextView) d
+                    .findViewById(R.id.details_resolution_value))
+                    .setText(dimensionsString);
+
+                String dateString = "";
+                long dateTaken = image.getDateTaken();
+                if (dateTaken != 0) {
+                    Date date = new Date(image.getDateTaken());
+                    SimpleDateFormat dateFormat = new SimpleDateFormat();
+                    dateString = dateFormat.format(date);
+
+                    ((TextView) d
+                            .findViewById(R.id.details_date_taken_value))
+                            .setText(dateString);
+                } else {
+                    d.findViewById(R.id.details_date_taken_row)
+                            .setVisibility(View.GONE);
+                }
+
+                builder.setNeutralButton(R.string.details_ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog,
+                                    int which) {
+                                dialog.dismiss();
+                            }
+                        });
+
+                builder.setIcon(android.R.drawable.ic_dialog_info)
+                        .setTitle(R.string.details_panel_title)
+                        .setView(d)
+                        .show();
+            }
+        });
+        return true;
+    }
+
+    private static boolean onRotateLeftClicked(MenuInvoker onInvoke) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (image == null || image.isReadonly()) {
+                    return;
+                }
+                image.rotateImageBy(-90);
+            }
+        });
+        return true;
+    }
+
+    private static boolean onRotateRightClicked(MenuInvoker onInvoke) {    
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (image == null || image.isReadonly()) {
+                    return;
+                }
+                image.rotateImageBy(90);
+            }
+        });
+        return true;
+    }
+
+    private static boolean onCropClicked(MenuInvoker onInvoke,
+                                         final Activity activity) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (u == null) {
+                    return;
+                }
+
+                Intent cropIntent = new Intent();
+                cropIntent.setClass(activity, CropImage.class);
+                cropIntent.setData(u);
+                activity.startActivityForResult(cropIntent,
+                        RESULT_COMMON_MENU_CROP);
+            }
+        });
+        return true;
+    }
+
+    private static boolean onImageSaveClicked(MenuInvoker onInvoke,
+                                              final Activity activity) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (u == null || image == null) {
+                    return;
+                }
+
+                if (Config.LOGV) {
+                    Log.v(TAG, "in callback u is " + u + "; mime type is "
+                            + image.getMimeType());
+                }
+                Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
+                intent.setDataAndType(u, image.getMimeType());
+                intent.putExtra("mimeType", image.getMimeType());
+                activity.startActivity(Intent.createChooser(intent,
+                        activity.getText(R.string.setImage)));
+            }
+        });
+        return true;
+    }
+
+    private static boolean onImageShareClicked(MenuInvoker onInvoke,
+            final Activity activity, final boolean isImage) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri u, IImage image) {
+                if (image == null) return;
+                if (!isImage && getImageFileSize(image)
+                        > SHARE_FILE_LENGTH_LIMIT) {
+                    Toast.makeText(activity,
+                            R.string.too_large_to_attach,
+                            Toast.LENGTH_LONG).show();
+                    return;
+                }
+
+                Intent intent = new Intent();
+                intent.setAction(Intent.ACTION_SEND);
+                String mimeType = image.getMimeType();
+                intent.setType(mimeType);
+                intent.putExtra(Intent.EXTRA_STREAM, u);
+                boolean isImage = ImageManager.isImageMimeType(mimeType);
+                try {
+                    activity.startActivity(Intent.createChooser(intent,
+                            activity.getText(isImage
+                            ? R.string.sendImage
+                            : R.string.sendVideo)));
+                } catch (android.content.ActivityNotFoundException ex) {
+                    Toast.makeText(activity, isImage
+                            ? R.string.no_way_to_share_image
+                            : R.string.no_way_to_share_video,
+                            Toast.LENGTH_SHORT).show();
+                }
+            }
+        });
+        return true;
+    }
+
+    private static boolean onViewPlayClicked(MenuInvoker onInvoke,
+            final Activity activity) {
+        onInvoke.run(new MenuCallback() {
+            public void run(Uri uri, IImage image) {
+                if (image != null) {
+                    Intent intent = new Intent(Intent.ACTION_VIEW,
+                            image.fullSizeImageUri());
+                    activity.startActivity(intent);
+                }
+            }});
+        return true;
+    }
+
     static MenuItemsResult addImageMenuItems(
             Menu menu,
             int inclusions,
@@ -150,305 +454,101 @@
             final Handler handler,
             final Runnable onDelete,
             final MenuInvoker onInvoke) {
-        final ArrayList<MenuItem> requiresWriteAccessItems = new ArrayList<MenuItem>();
-        final ArrayList<MenuItem> requiresNoDrmAccessItems = new ArrayList<MenuItem>();
+        final ArrayList<MenuItem> requiresWriteAccessItems =
+                new ArrayList<MenuItem>();
+        final ArrayList<MenuItem> requiresNoDrmAccessItems =
+                new ArrayList<MenuItem>();
 
         if (isImage && ((inclusions & INCLUDE_ROTATE_MENU) != 0)) {
-            SubMenu rotateSubmenu = menu.addSubMenu(IMAGE_SAVING_ITEM, MENU_IMAGE_ROTATE,
-                    40, R.string.rotate).setIcon(android.R.drawable.ic_menu_rotate);
+            SubMenu rotateSubmenu = menu.addSubMenu(IMAGE_SAVING_ITEM,
+                    MENU_IMAGE_ROTATE, 40, R.string.rotate)
+                    .setIcon(android.R.drawable.ic_menu_rotate);
             // Don't show the rotate submenu if the item at hand is read only
-            // since the items within the submenu won't be shown anyway.  This is
-            // really a framework bug in that it shouldn't show the submenu if
-            // the submenu has no visible items.
+            // since the items within the submenu won't be shown anyway. This
+            // is really a framework bug in that it shouldn't show the submenu
+            // if the submenu has no visible items.
             requiresWriteAccessItems.add(rotateSubmenu.getItem());
             if (rotateSubmenu != null) {
-                requiresWriteAccessItems.add(rotateSubmenu.add(0, MENU_IMAGE_ROTATE_LEFT, 50, R.string.rotate_left).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                    public boolean onMenuItemClick(MenuItem item) {
-                        onInvoke.run(new MenuCallback() {
-                            public void run(Uri u, IImage image) {
-                                if (image == null || image.isReadonly())
-                                    return;
-                                image.rotateImageBy(-90);
+                requiresWriteAccessItems.add(
+                        rotateSubmenu.add(0, MENU_IMAGE_ROTATE_LEFT, 50,
+                        R.string.rotate_left)
+                        .setOnMenuItemClickListener(
+                        new MenuItem.OnMenuItemClickListener() {
+                            public boolean onMenuItemClick(MenuItem item) {
+                                return onRotateLeftClicked(onInvoke);
                             }
-                        });
-                        return true;
-                    }
-                }).setAlphabeticShortcut('l'));
-                requiresWriteAccessItems.add(rotateSubmenu.add(0, MENU_IMAGE_ROTATE_RIGHT, 60, R.string.rotate_right).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                    public boolean onMenuItemClick(MenuItem item) {
-                        onInvoke.run(new MenuCallback() {
-                            public void run(Uri u, IImage image) {
-                                if (image == null || image.isReadonly())
-                                    return;
-
-                                image.rotateImageBy(90);
+                        }).setAlphabeticShortcut('l'));
+                requiresWriteAccessItems.add(
+                        rotateSubmenu.add(0, MENU_IMAGE_ROTATE_RIGHT, 60,
+                        R.string.rotate_right)
+                        .setOnMenuItemClickListener(
+                        new MenuItem.OnMenuItemClickListener() {
+                            public boolean onMenuItemClick(MenuItem item) {
+                                return onRotateRightClicked(onInvoke);
                             }
-                        });
-                        return true;
-                    }
-                }).setAlphabeticShortcut('r'));
+                        }).setAlphabeticShortcut('r'));
             }
         }
 
         if (isImage && ((inclusions & INCLUDE_CROP_MENU) != 0)) {
             MenuItem autoCrop = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_CROP, 73,
-                    R.string.camera_crop).setOnMenuItemClickListener(
-                            new MenuItem.OnMenuItemClickListener() {
-                public boolean onMenuItemClick(MenuItem item) {
-                    onInvoke.run(new MenuCallback() {
-                        public void run(Uri u, IImage image) {
-                            if (u == null)
-                                return;
-
-                            Intent cropIntent = new Intent();
-                            cropIntent.setClass(activity, CropImage.class);
-                            cropIntent.setData(u);
-                            activity.startActivityForResult(cropIntent, RESULT_COMMON_MENU_CROP);
+                    R.string.camera_crop);
+            autoCrop.setIcon(android.R.drawable.ic_menu_crop);
+            autoCrop.setOnMenuItemClickListener(
+                    new MenuItem.OnMenuItemClickListener() {
+                        public boolean onMenuItemClick(MenuItem item) {
+                            return onCropClicked(onInvoke, activity);
                         }
                     });
-                    return true;
-                }
-            });
-            autoCrop.setIcon(android.R.drawable.ic_menu_crop);
             requiresWriteAccessItems.add(autoCrop);
         }
 
         if (isImage && ((inclusions & INCLUDE_SET_MENU) != 0)) {
-            MenuItem setMenu = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SET, 75, R.string.camera_set);
+            MenuItem setMenu = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SET, 75,
+                    R.string.camera_set);
             setMenu.setIcon(android.R.drawable.ic_menu_set_as);
-
-            setMenu.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                public boolean onMenuItemClick(MenuItem item) {
-                    onInvoke.run(new MenuCallback() {
-                        public void run(Uri u, IImage image) {
-                            if (u == null || image == null)
-                                return;
-
-                            if (Config.LOGV)
-                                Log.v(TAG, "in callback u is " + u + "; mime type is " + image.getMimeType());
-                            Intent intent = new Intent(Intent.ACTION_ATTACH_DATA);
-                            intent.setDataAndType(u, image.getMimeType());
-                            intent.putExtra("mimeType", image.getMimeType());
-                            activity.startActivity(Intent.createChooser(intent, activity.getText(R.string.setImage)));
+            setMenu.setOnMenuItemClickListener(
+                    new MenuItem.OnMenuItemClickListener() {
+                        public boolean onMenuItemClick(MenuItem item) {
+                            return onImageSaveClicked(onInvoke, activity);
                         }
                     });
-                    return true;
-                }
-            });
         }
 
         if ((inclusions & INCLUDE_SHARE_MENU) != 0) {
-            if (Config.LOGV)
-                Log.v(TAG, ">>>>> add share");
             MenuItem item1 = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_SHARE, 10,
                     R.string.camera_share).setOnMenuItemClickListener(
                     new MenuItem.OnMenuItemClickListener() {
-                public boolean onMenuItemClick(MenuItem item) {
-                    onInvoke.run(new MenuCallback() {
-                        public void run(Uri u, IImage image) {
-                            if (image == null) return;
-                            if (!isImage && getImageFileSize(image) > SHARE_FILE_LENGTH_LIMIT ) {
-                                Toast.makeText(activity,
-                                        R.string.too_large_to_attach, Toast.LENGTH_LONG).show();
-                                return;
-                            }
-
-                            Intent intent = new Intent();
-                            intent.setAction(Intent.ACTION_SEND);
-                            String mimeType = image.getMimeType();
-                            intent.setType(mimeType);
-                            intent.putExtra(Intent.EXTRA_STREAM, u);
-                            boolean isImage = ImageManager.isImageMimeType(mimeType);
-                            try {
-                                activity.startActivity(Intent.createChooser(intent,
-                                        activity.getText(
-                                                isImage ? R.string.sendImage : R.string.sendVideo)));
-                            } catch (android.content.ActivityNotFoundException ex) {
-                                Toast.makeText(activity,
-                                        isImage ? R.string.no_way_to_share_image
-                                                : R.string.no_way_to_share_video,
-                                                Toast.LENGTH_SHORT).show();
-                            }
+                        public boolean onMenuItemClick(MenuItem item) {
+                            return onImageShareClicked(onInvoke, activity,
+                                    isImage);
                         }
                     });
-                    return true;
-                }
-            });
             item1.setIcon(android.R.drawable.ic_menu_share);
             MenuItem item = item1;
             requiresNoDrmAccessItems.add(item);
         }
 
         if ((inclusions & INCLUDE_DELETE_MENU) != 0) {
-            MenuItem deleteItem = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_TOSS, 70, R.string.camera_toss);
+            MenuItem deleteItem = menu.add(IMAGE_SAVING_ITEM, MENU_IMAGE_TOSS,
+                    70, R.string.camera_toss);
             requiresWriteAccessItems.add(deleteItem);
-            deleteItem.setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
-                public boolean onMenuItemClick(MenuItem item) {
-                    deleteImpl(activity, onDelete, isImage);
-                    return true;
-                }
-            })
-            .setAlphabeticShortcut('d')
-            .setIcon(android.R.drawable.ic_menu_delete);
+            deleteItem.setOnMenuItemClickListener(
+                    new MenuItem.OnMenuItemClickListener() {
+                        public boolean onMenuItemClick(MenuItem item) {
+                            deleteImpl(activity, onDelete, isImage);
+                            return true;
+                        }
+                    })
+                    .setAlphabeticShortcut('d')
+                    .setIcon(android.R.drawable.ic_menu_delete);
         }
 
         if ((inclusions & INCLUDE_DETAILS_MENU) != 0) {
-            MenuItem detailsMenu = menu.add(0, 0, 80, R.string.details).setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+            MenuItem detailsMenu = menu.add(0, 0, 80, R.string.details)
+            .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
                 public boolean onMenuItemClick(MenuItem item) {
-                    onInvoke.run(new MenuCallback() {
-                        public void run(Uri u, IImage image) {
-                            if (image == null)
-                                return;
-
-                            AlertDialog.Builder builder = new AlertDialog.Builder(activity);
-
-                            final View d = View.inflate(activity, R.layout.detailsview, null);
-
-                            ImageView imageView = (ImageView) d.findViewById(R.id.details_thumbnail_image);
-                            imageView.setImageBitmap(image.miniThumbBitmap());
-
-                            TextView textView = (TextView) d.findViewById(R.id.details_image_title);
-                            textView.setText(image.getDisplayName());
-
-                            long length = getImageFileSize(image);
-                            String lengthString = lengthString = length < 0 ? ""
-                                    : android.text.format.Formatter.formatFileSize(activity, length);
-                            ((TextView)d.findViewById(R.id.details_file_size_value))
-                                .setText(lengthString);
-
-                            int dimensionWidth = 0;
-                            int dimensionHeight = 0;
-                            if (isImage) {
-                                dimensionWidth = image.getWidth();
-                                dimensionHeight = image.getHeight();
-                                d.findViewById(R.id.details_duration_row).setVisibility(View.GONE);
-                                d.findViewById(R.id.details_frame_rate_row).setVisibility(View.GONE);
-                                d.findViewById(R.id.details_bit_rate_row).setVisibility(View.GONE);
-                                d.findViewById(R.id.details_format_row).setVisibility(View.GONE);
-                                d.findViewById(R.id.details_codec_row).setVisibility(View.GONE);
-                            } else {
-                                MediaMetadataRetriever retriever = new MediaMetadataRetriever();
-                                try {
-                                    retriever.setMode(MediaMetadataRetriever.MODE_GET_METADATA_ONLY);
-                                    retriever.setDataSource(image.getDataPath());
-                                    try {
-                                        dimensionWidth = Integer.parseInt(
-                                                retriever.extractMetadata(
-                                                MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH));
-                                        dimensionHeight = Integer.parseInt(
-                                                retriever.extractMetadata(
-                                                MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT));
-                                    } catch (NumberFormatException e) {
-                                        dimensionWidth = 0;
-                                        dimensionHeight = 0;
-                                    }
-
-                                    try {
-                                        int durationMs = Integer.parseInt(retriever.extractMetadata(
-                                                MediaMetadataRetriever.METADATA_KEY_DURATION));
-                                        String durationValue = formatDuration(
-                                                activity, durationMs);
-                                        ((TextView)d.findViewById(R.id.details_duration_value))
-                                            .setText(durationValue);
-                                    } catch (NumberFormatException e) {
-                                        d.findViewById(R.id.details_frame_rate_row)
-                                        .setVisibility(View.GONE);
-                                    }
-
-                                    try {
-                                        String frame_rate = String.format(
-                                                activity.getString(R.string.details_fps),
-                                                Integer.parseInt(
-                                                        retriever.extractMetadata(
-                                                                MediaMetadataRetriever.METADATA_KEY_FRAME_RATE)));
-                                        ((TextView)d.findViewById(R.id.details_frame_rate_value))
-                                            .setText(frame_rate);
-                                    } catch (NumberFormatException e) {
-                                        d.findViewById(R.id.details_frame_rate_row)
-                                        .setVisibility(View.GONE);
-                                    }
-
-                                    try {
-                                        long bitRate = Long.parseLong(retriever.extractMetadata(
-                                                MediaMetadataRetriever.METADATA_KEY_BIT_RATE));
-                                        String bps;
-                                        if (bitRate < 1000000) {
-                                            bps = String.format(
-                                                    activity.getString(R.string.details_kbps),
-                                                    bitRate / 1000);
-                                        } else {
-                                            bps = String.format(
-                                                    activity.getString(R.string.details_mbps),
-                                                    ((double) bitRate) / 1000000.0);
-                                        }
-                                        ((TextView)d.findViewById(R.id.details_bit_rate_value))
-                                                .setText(bps);
-                                    } catch (NumberFormatException e) {
-                                        d.findViewById(R.id.details_bit_rate_row)
-                                                .setVisibility(View.GONE);
-                                    }
-
-                                    String format = retriever.extractMetadata(
-                                            MediaMetadataRetriever.METADATA_KEY_VIDEO_FORMAT);
-                                    ((TextView)d.findViewById(R.id.details_format_value))
-                                        .setText(format);
-
-                                    String codec = retriever.extractMetadata(
-                                                MediaMetadataRetriever.METADATA_KEY_CODEC);
-
-                                    if (codec == null) {
-                                        d.findViewById(R.id.details_codec_row).
-                                            setVisibility(View.GONE);
-                                    } else {
-                                        ((TextView)d.findViewById(R.id.details_codec_value))
-                                            .setText(codec);
-                                    }
-                                } catch(RuntimeException ex) {
-                                    // Assume this is a corrupt video file.
-                                } finally {
-                                    try {
-                                        retriever.release();
-                                    } catch (RuntimeException ex) {
-                                        // Ignore failures while cleaning up.
-                                    }
-                                }
-                            }
-
-                            String dimensionsString = String.format(
-                                    activity.getString(R.string.details_dimension_x),
-                                    dimensionWidth, dimensionHeight);
-                            ((TextView)d.findViewById(R.id.details_resolution_value))
-                                .setText(dimensionsString);
-
-                            String dateString = "";
-                            long dateTaken = image.getDateTaken();
-                            if (dateTaken != 0) {
-                                java.util.Date date = new java.util.Date(image.getDateTaken());
-                                java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat();
-                                dateString = dateFormat.format(date);
-
-                                ((TextView)d.findViewById(R.id.details_date_taken_value))
-                                    .setText(dateString);
-                            } else {
-                                d.findViewById(R.id.details_date_taken_row)
-                                    .setVisibility(View.GONE);
-                            }
-
-                            builder.setNeutralButton(R.string.details_ok,
-                                    new DialogInterface.OnClickListener() {
-                                    public void onClick(DialogInterface dialog, int which) {
-                                        dialog.dismiss();
-                                    }
-                                });
-
-                            builder.setIcon(android.R.drawable.ic_dialog_info)
-                                .setTitle(R.string.details_panel_title)
-                                .setView(d)
-                                .show();
-
-                        }
-                    });
-                    return true;
+                    return onDetailsClicked(onInvoke, activity, isImage);
                 }
             });
             detailsMenu.setIcon(R.drawable.ic_menu_view_details);
@@ -456,17 +556,10 @@
 
         if ((!isImage) && ((inclusions & INCLUDE_VIEWPLAY_MENU) != 0)) {
             menu.add(VIDEO_SAVING_ITEM, MENU_VIDEO_PLAY, 0, R.string.video_play)
-                .setOnMenuItemClickListener(new MenuItem.OnMenuItemClickListener() {
+                .setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
                 public boolean onMenuItemClick(MenuItem item) {
-                    onInvoke.run(new MenuCallback() {
-                        public void run(Uri uri, IImage image) {
-                            if (image != null) {
-                                Intent intent = new Intent(Intent.ACTION_VIEW,
-                                        image.fullSizeImageUri());
-                                activity.startActivity(intent);
-                            }
-                        }});
-                    return true;
+                    return onViewPlayClicked(onInvoke, activity);
                 }
             });
         }
@@ -474,29 +567,33 @@
 
         return new MenuItemsResult() {
             public void gettingReadyToOpen(Menu menu, IImage image) {
-                // protect against null here.  this isn't strictly speaking required
-                // but if a client app isn't handling sdcard removal properly it
-                // could happen
+                // protect against null here.  this isn't strictly speaking
+                // required but if a client app isn't handling sdcard removal
+                // properly it could happen
                 if (image == null) {
                     return;
                 }
                 boolean readOnly = image.isReadonly();
                 boolean isDrm = image.isDrm();
-                if (Config.LOGV)
+                if (Config.LOGV) {
                     Log.v(TAG, "readOnly: " + readOnly + "; drm: " + isDrm);
-                for (MenuItem item: requiresWriteAccessItems) {
-                    if (Config.LOGV)
-                        Log.v(TAG, "item is " + item.toString());
-                      item.setVisible(!readOnly);
-                      item.setEnabled(!readOnly);
                 }
-                for (MenuItem item: requiresNoDrmAccessItems) {
-                    if (Config.LOGV)
+                for (MenuItem item : requiresWriteAccessItems) {
+                    if (Config.LOGV) {
                         Log.v(TAG, "item is " + item.toString());
-                      item.setVisible(!isDrm);
-                      item.setEnabled(!isDrm);
+                    }
+                    item.setVisible(!readOnly);
+                    item.setEnabled(!readOnly);
+                }
+                for (MenuItem item : requiresNoDrmAccessItems) {
+                    if (Config.LOGV) {
+                        Log.v(TAG, "item is " + item.toString());
+                    }
+                    item.setVisible(!isDrm);
+                    item.setEnabled(!isDrm);
                 }
             }
+        
             public void aboutToCall(MenuItem menu, IImage image) {
             }
         };
@@ -510,17 +607,22 @@
         deleteImpl(activity, onDelete, false);
     }
 
-    static void deleteImage(Activity activity, Runnable onDelete, IImage image) {
+    static void deleteImage(Activity activity, Runnable onDelete,
+            IImage image) {
         if (image != null) {
             deleteImpl(activity, onDelete, ImageManager.isImage(image));
         }
     }
 
-    private static void deleteImpl(Activity activity, final Runnable onDelete, boolean isPhoto) {
-        boolean confirm = android.preference.PreferenceManager.getDefaultSharedPreferences(activity).getBoolean("pref_gallery_confirm_delete_key", true);
+    private static void deleteImpl(Activity activity, final Runnable onDelete,
+            boolean isPhoto) {
+        boolean confirm = android.preference.PreferenceManager
+                .getDefaultSharedPreferences(activity)
+                .getBoolean("pref_gallery_confirm_delete_key", true);
         if (!confirm) {
-            if (onDelete != null)
+            if (onDelete != null) {
                 onDelete.run();
+            }
         } else {
             displayDeleteDialog(activity, onDelete, isPhoto);
         }
@@ -528,45 +630,55 @@
 
     public static void displayDeleteDialog(Activity activity,
             final Runnable onDelete, boolean isPhoto) {
-        android.app.AlertDialog.Builder b = new android.app.AlertDialog.Builder(activity);
+        android.app.AlertDialog.Builder b =
+                new android.app.AlertDialog.Builder(activity);
         b.setIcon(android.R.drawable.ic_dialog_alert);
         b.setTitle(R.string.confirm_delete_title);
-        b.setMessage(isPhoto? R.string.confirm_delete_message
+        b.setMessage(isPhoto
+                ? R.string.confirm_delete_message
                 : R.string.confirm_delete_video_message);
-        b.setPositiveButton(android.R.string.ok, new android.content.DialogInterface.OnClickListener() {
-            public void onClick(android.content.DialogInterface v, int x) {
-                if (onDelete != null)
-                    onDelete.run();
-            }
-        });
-        b.setNegativeButton(android.R.string.cancel, new android.content.DialogInterface.OnClickListener() {
-            public void onClick(android.content.DialogInterface v, int x) {
-
-            }
-        });
+        b.setPositiveButton(android.R.string.ok,
+                new android.content.DialogInterface.OnClickListener() {
+                    public void onClick(android.content.DialogInterface v,
+                                        int x) {
+                        if (onDelete != null) {
+                            onDelete.run();
+                        }
+                    }
+                });
+        b.setNegativeButton(android.R.string.cancel,
+                new android.content.DialogInterface.OnClickListener() {
+                    public void onClick(android.content.DialogInterface v,
+                                        int x) {
+                    }
+                });
         b.create().show();
     }
 
     static void addSwitchModeMenuItem(Menu menu, final Activity activity,
             final boolean switchToVideo) {
-        int group = switchToVideo ? MenuHelper.IMAGE_MODE_ITEM : MenuHelper.VIDEO_MODE_ITEM;
-        int labelId = switchToVideo ? R.string.switch_to_video_lable
+        int group = switchToVideo
+                ? MenuHelper.IMAGE_MODE_ITEM
+                : MenuHelper.VIDEO_MODE_ITEM;
+        int labelId = switchToVideo
+                ? R.string.switch_to_video_lable
                 : R.string.switch_to_camera_lable;
-        int iconId = switchToVideo ? R.drawable.ic_menu_camera_video_view
+        int iconId = switchToVideo
+                ? R.drawable.ic_menu_camera_video_view
                 : android.R.drawable.ic_menu_camera;
-        MenuItem item = menu.add(group, MENU_SWITCH_CAMERA_MODE, 0,
-                labelId).setOnMenuItemClickListener(
-                        new OnMenuItemClickListener() {
-            public boolean onMenuItemClick(MenuItem item) {
-                String action = switchToVideo ? MediaStore.INTENT_ACTION_VIDEO_CAMERA
-                        : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA;
-                Intent intent = new Intent(action);
-                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
-                activity.startActivity(intent);
-                return true;
-             }
-        });
+        MenuItem item = menu.add(group, MENU_SWITCH_CAMERA_MODE, 0, labelId)
+                .setOnMenuItemClickListener(new OnMenuItemClickListener() {
+                    public boolean onMenuItemClick(MenuItem item) {
+                        String action = switchToVideo
+                                ? MediaStore.INTENT_ACTION_VIDEO_CAMERA
+                                : MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA;
+                        Intent intent = new Intent(action);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);
+                        activity.startActivity(intent);
+                        return true;
+                     }
+                });
         item.setIcon(iconId);
     }
 
@@ -581,7 +693,8 @@
     }
 
     static void gotoCameraImageGallery(Activity activity) {
-        gotoGallery(activity, R.string.gallery_camera_bucket_name, ImageManager.INCLUDE_IMAGES);
+        gotoGallery(activity, R.string.gallery_camera_bucket_name,
+                ImageManager.INCLUDE_IMAGES);
     }
 
     static void gotoCameraVideoGallery(Activity activity) {
@@ -589,19 +702,24 @@
                 ImageManager.INCLUDE_VIDEOS);
     }
 
-    static private void gotoGallery(Activity activity, int windowTitleId, int mediaTypes) {
-        Uri target = Images.Media.INTERNAL_CONTENT_URI.buildUpon().appendQueryParameter("bucketId",
+    private static void gotoGallery(Activity activity, int windowTitleId,
+            int mediaTypes) {
+        Uri target = Images.Media.INTERNAL_CONTENT_URI.buildUpon()
+                .appendQueryParameter("bucketId",
                 ImageManager.CAMERA_IMAGE_BUCKET_ID).build();
         Intent intent = new Intent(Intent.ACTION_VIEW, target);
         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
         intent.putExtra("windowTitle", activity.getString(windowTitleId));
         intent.putExtra("mediaTypes", mediaTypes);
-        // Request unspecified so that we match the current camera orientation rather than
-        // matching the "flip orientation" preference.
+
+        // Request unspecified so that we match the current camera orientation
+        // rather than matching the "flip orientation" preference.
         // Disabled because people don't care for it. Also it's
-        // not as compelling now that we have implemented have quick orientation flipping.
+        // not as compelling now that we have implemented have quick orientation
+        // flipping.
         // intent.putExtra(MediaStore.EXTRA_SCREEN_ORIENTATION,
-        //        android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+        //         android.content.pm.ActivityInfo
+        //         .SCREEN_ORIENTATION_UNSPECIFIED);
         try {
             activity.startActivity(intent);
         } catch (ActivityNotFoundException e) {
@@ -611,38 +729,38 @@
 
     static void addCapturePictureMenuItems(Menu menu, final Activity activity) {
         menu.add(0, MENU_CAPTURE_PICTURE, 1, R.string.capture_picture)
-            .setOnMenuItemClickListener(
-                 new MenuItem.OnMenuItemClickListener() {
-                     public boolean onMenuItemClick(MenuItem item) {
-                        Intent intent = new Intent(MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
+                .setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
+                    public boolean onMenuItemClick(MenuItem item) {
+                        Intent intent = new Intent(
+                                MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                         try {
-                               activity.startActivity(intent);
+                            activity.startActivity(intent);
                         } catch (android.content.ActivityNotFoundException e) {
                             // Ignore exception
                         }
-                return true;
-            }
-        })
-        .setIcon(android.R.drawable.ic_menu_camera);
+                        return true;
+                    }
+                }).setIcon(android.R.drawable.ic_menu_camera);
     }
 
     static void addCaptureVideoMenuItems(Menu menu, final Activity activity) {
         menu.add(0, MENU_CAPTURE_VIDEO, 2, R.string.capture_video)
-            .setOnMenuItemClickListener(
-                 new MenuItem.OnMenuItemClickListener() {
-                     public boolean onMenuItemClick(MenuItem item) {
-                         Intent intent = new Intent(MediaStore.INTENT_ACTION_VIDEO_CAMERA);
-                         intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
-                         try {
-                             activity.startActivity(intent);
-                         } catch (android.content.ActivityNotFoundException e) {
-                             // Ignore exception
-                         }
-                return true;
-            }
-        })
-        .setIcon(R.drawable.ic_menu_camera_video_view);
+                .setOnMenuItemClickListener(
+                new MenuItem.OnMenuItemClickListener() {
+                    public boolean onMenuItemClick(MenuItem item) {
+                        Intent intent = new Intent(
+                                MediaStore.INTENT_ACTION_VIDEO_CAMERA);
+                        intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+                        try {
+                            activity.startActivity(intent);
+                        } catch (android.content.ActivityNotFoundException e) {
+                            // Ignore exception
+                        }
+                        return true;
+                    }
+                }).setIcon(R.drawable.ic_menu_camera_video_view);
     }
 
     static void addCaptureMenuItems(Menu menu, final Activity activity) {
@@ -650,48 +768,61 @@
         addCaptureVideoMenuItems(menu, activity);
     }
 
-    static MenuItem addFlipOrientation(Menu menu, final Activity activity, final SharedPreferences prefs) {
+    private static boolean onFlipOrientationClicked(Activity activity,
+            SharedPreferences prefs) {
+        // Check what our actual orientation is
+        int current = activity.getResources().getConfiguration().orientation;
+        int newOrientation = android.content.pm.ActivityInfo
+                .SCREEN_ORIENTATION_LANDSCAPE;
+        if (current == Configuration.ORIENTATION_LANDSCAPE) {
+            newOrientation = android.content.pm.ActivityInfo
+                    .SCREEN_ORIENTATION_UNSPECIFIED;
+        }
+        SharedPreferences.Editor editor = prefs.edit();
+        editor.putInt("nuorientation", newOrientation);
+        editor.commit();
+        requestOrientation(activity, prefs, true);
+        return true;
+    }
+
+    static MenuItem addFlipOrientation(Menu menu, final Activity activity,
+            final SharedPreferences prefs) {
         // position 41 after rotate
         // D
         return menu
-                .add(Menu.CATEGORY_SECONDARY, 304, 41, R.string.flip_orientation)
+                .add(Menu.CATEGORY_SECONDARY, 304, 41,
+                R.string.flip_orientation)
                 .setOnMenuItemClickListener(
-                        new MenuItem.OnMenuItemClickListener() {
-            public boolean onMenuItemClick(MenuItem item) {
-                // Check what our actual orientation is
-                int current = activity.getResources().getConfiguration().orientation;
-                int newOrientation = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
-                if (current == Configuration.ORIENTATION_LANDSCAPE) {
-                    newOrientation = android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
-                }
-                SharedPreferences.Editor editor = prefs.edit();
-                editor.putInt("nuorientation", newOrientation);
-                editor.commit();
-                requestOrientation(activity, prefs, true);
-                return true;
-            }
-        })
-        .setIcon(android.R.drawable.ic_menu_always_landscape_portrait);
+                new MenuItem.OnMenuItemClickListener() {
+                    public boolean onMenuItemClick(MenuItem item) {
+                        return onFlipOrientationClicked(activity, prefs);
+                    }
+                }).setIcon(
+                android.R.drawable.ic_menu_always_landscape_portrait);
     }
 
     static void requestOrientation(Activity activity, SharedPreferences prefs) {
         requestOrientation(activity, prefs, false);
     }
 
-    static private void requestOrientation(Activity activity, SharedPreferences prefs,
-            boolean ignoreIntentExtra) {
-        // Disable orientation for now. If it is set to SCREEN_ORIENTATION_SENSOR,
-        // a duplicated orientation will be observed.
+    private static void requestOrientation(Activity activity,
+            SharedPreferences prefs, boolean ignoreIntentExtra) {
+        // Disable orientation for now. If it is set to
+        // SCREEN_ORIENTATION_SENSOR, a duplicated orientation will be observed.
 
         return;
     }
 
-    static void setFlipOrientationEnabled(Activity activity, MenuItem flipItem) {
-        int keyboard = activity.getResources().getConfiguration().hardKeyboardHidden;
-        flipItem.setEnabled(keyboard != android.content.res.Configuration.HARDKEYBOARDHIDDEN_NO);
+    static void setFlipOrientationEnabled(Activity activity,
+            MenuItem flipItem) {
+        int keyboard = activity.getResources().getConfiguration()
+                .hardKeyboardHidden;
+        flipItem.setEnabled(keyboard != android.content.res.Configuration
+                .HARDKEYBOARDHIDDEN_NO);
     }
 
-    public static String formatDuration(final Activity activity, int durationMs) {
+    public static String formatDuration(final Activity activity,
+            int durationMs) {
         int duration = durationMs / 1000;
         int h = duration / 3600;
         int m = (duration - h * 3600) / 60;
@@ -708,7 +839,7 @@
     }
 
     public static void showStorageToast(Activity activity) {
-      showStorageToast(activity, calculatePicturesRemaining());
+        showStorageToast(activity, calculatePicturesRemaining());
     }
 
     public static void showStorageToast(Activity activity, int remaining) {
@@ -735,10 +866,12 @@
             if (!ImageManager.hasStorage()) {
                 return NO_STORAGE_ERROR;
             } else {
-                String storageDirectory = Environment.getExternalStorageDirectory().toString();
+                String storageDirectory =
+                        Environment.getExternalStorageDirectory().toString();
                 StatFs stat = new StatFs(storageDirectory);
-                float remaining = ((float)stat.getAvailableBlocks() * (float)stat.getBlockSize()) / 400000F;
-                return (int)remaining;
+                float remaining = ((float) stat.getAvailableBlocks()
+                        * (float) stat.getBlockSize()) / 400000F;
+                return (int) remaining;
             }
         } catch (Exception ex) {
             // if we can't stat the filesystem then we don't know how many
@@ -748,4 +881,3 @@
         }
     }
 }
-
