diff --git a/res/layout/ingest_activity_item_list.xml b/res/layout/ingest_activity_item_list.xml
index f0e91e8..b91f0ce 100644
--- a/res/layout/ingest_activity_item_list.xml
+++ b/res/layout/ingest_activity_item_list.xml
@@ -52,6 +52,7 @@
             android:id="@+id/ingest_warning_view_text"
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
+            android:layout_marginStart="10dip"
             android:layout_marginLeft="10dip"
             android:textAppearance="?android:attr/textAppearanceSmall" />
     </LinearLayout>
diff --git a/res/layout/ingest_date_tile.xml b/res/layout/ingest_date_tile.xml
index 6b5e934..8cd63e9 100644
--- a/res/layout/ingest_date_tile.xml
+++ b/res/layout/ingest_date_tile.xml
@@ -27,7 +27,7 @@
             android:layout_height="wrap_content"
             android:layout_column="0"
             android:layout_row="0"
-            android:layout_gravity="bottom|right"
+            android:layout_gravity="bottom|end"
             android:layout_marginTop="7sp"
             android:includeFontPadding="false"
             android:textSize="16sp"
@@ -40,7 +40,7 @@
             android:layout_height="wrap_content"
             android:layout_column="0"
             android:layout_row="1"
-            android:layout_gravity="top|right"
+            android:layout_gravity="top|end"
             android:includeFontPadding="false"
             android:textSize="13sp"
             android:fontFamily="sans-serif-light"
@@ -52,7 +52,8 @@
             android:layout_column="1"
             android:layout_row="0"
             android:layout_rowSpan="2"
-            android:layout_gravity="top|left"
+            android:layout_gravity="top|start"
+            android:layout_marginStart="5sp"
             android:layout_marginLeft="5sp"
             android:includeFontPadding="false"
             android:textSize="44sp"
diff --git a/res/layout/ingest_fullsize.xml b/res/layout/ingest_fullsize.xml
index fad596c..d57c4ae 100644
--- a/res/layout/ingest_fullsize.xml
+++ b/res/layout/ingest_fullsize.xml
@@ -37,7 +37,8 @@
         android:layout_width="wrap_content"
         android:layout_height="wrap_content"
         android:layout_alignParentBottom="true"
+        android:layout_alignParentEnd="true"
         android:layout_alignParentRight="true"
-        android:text="@string/Import" />
+        android:text="@string/ingest_import" />
 
 </com.android.gallery3d.ingest.ui.MtpFullscreenView>
\ No newline at end of file
diff --git a/res/layout/ingest_thumbnail.xml b/res/layout/ingest_thumbnail.xml
index 6907149..b36ec93 100644
--- a/res/layout/ingest_thumbnail.xml
+++ b/res/layout/ingest_thumbnail.xml
@@ -17,6 +17,4 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
-    android:scaleType="centerCrop"
-    android:background="@drawable/ingest_item_list_selector">
-</com.android.gallery3d.ingest.ui.MtpThumbnailTileView>
\ No newline at end of file
+    android:scaleType="centerCrop" />
diff --git a/res/menu/ingest_menu_item_list_selection.xml b/res/menu/ingest_menu_item_list_selection.xml
index 2f020b6..b3fa111 100644
--- a/res/menu/ingest_menu_item_list_selection.xml
+++ b/res/menu/ingest_menu_item_list_selection.xml
@@ -16,7 +16,7 @@
 <menu xmlns:android="http://schemas.android.com/apk/res/android">
     <item android:id="@+id/ingest_switch_view"
           android:showAsAction="always" />
-    <item android:id="@+id/import_items"
+    <item android:id="@+id/ingest_import_items"
           android:showAsAction="always|withText"
-          android:title="@string/Import" />
+          android:title="@string/ingest_import" />
 </menu>
\ No newline at end of file
diff --git a/res/values/ids.xml b/res/values/ids.xml
index fefd5f0..f5b4a48 100644
--- a/res/values/ids.xml
+++ b/res/values/ids.xml
@@ -20,4 +20,7 @@
     <item type="id" name="action_toggle_full_caching" />
     <item type="id" name="action_select_all" />
     <item type="id" name="viewpager" />
+
+    <item type="id" name="ingest_notification_scanning" />
+    <item type="id" name="ingest_notification_importing" />
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 1ef8c13..570014e 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -528,6 +528,12 @@
     <!-- The label on the button that will save an edited image -->
     <string name="save" msgid="8140440041190264400">Save</string>
 
+    <!-- A label representing the action of importing media item(s) [CHAR LIMIT=20] -->
+    <string name="ingest_import">@string/Import</string>
+
+    <!-- A label that indicates the media import operation completed [CHAR LIMIT=20] -->
+    <string name="ingest_import_complete">@string/import_complete</string>
+
     <!--  Text of notification message which is shown when user attaches camera -->
     <string name="ingest_scanning" msgid="2048262851775139720">Scanning content...</string>
 
@@ -538,6 +544,13 @@
         <item quantity="other">%1$d items scanned</item>
     </plurals>
 
+    <!-- String indicating how many media items from the camera have been selected -->
+    <plurals name="ingest_number_of_items_selected">
+        <item quantity="zero">%1$d items selected</item>
+        <item quantity="one">%1$d item selected</item>
+        <item quantity="other">%1$d items selected</item>
+    </plurals>
+
     <!--  Status message shown when content from the camera is being sorted -->
     <string name="ingest_sorting" msgid="624687230903648118">Sorting...</string>
 
@@ -553,6 +566,12 @@
     <!--  Status message shown when there is no MTP device connected  -->
     <string name="ingest_no_device">There is no MTP device connected</string>
 
+    <!-- Label for album grid button -->
+    <string name="ingest_switch_photo_grid">@string/switch_photo_grid</string>
+
+    <!-- Label for fullscreen button. [CHAR LIMIT=20] -->
+    <string name="ingest_switch_photo_fullscreen">@string/switch_photo_fullscreen</string>
+
     <!-- Camera resources below -->
 
     <!-- General strings -->
diff --git a/src/com/android/gallery3d/ingest/ImportTask.java b/src/com/android/gallery3d/ingest/ImportTask.java
deleted file mode 100644
index 7d2d641..0000000
--- a/src/com/android/gallery3d/ingest/ImportTask.java
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ingest;
-
-import android.content.Context;
-import android.mtp.MtpDevice;
-import android.mtp.MtpObjectInfo;
-import android.os.Environment;
-import android.os.PowerManager;
-
-import com.android.gallery3d.util.GalleryUtils;
-
-import java.io.File;
-import java.util.Collection;
-import java.util.LinkedList;
-import java.util.List;
-
-public class ImportTask implements Runnable {
-
-    public interface Listener {
-        void onImportProgress(int visitedCount, int totalCount, String pathIfSuccessful);
-
-        void onImportFinish(Collection<MtpObjectInfo> objectsNotImported, int visitedCount);
-    }
-
-    static private final String WAKELOCK_LABEL = "MTP Import Task";
-
-    private Listener mListener;
-    private String mDestAlbumName;
-    private Collection<MtpObjectInfo> mObjectsToImport;
-    private MtpDevice mDevice;
-    private PowerManager.WakeLock mWakeLock;
-
-    public ImportTask(MtpDevice device, Collection<MtpObjectInfo> objectsToImport,
-            String destAlbumName, Context context) {
-        mDestAlbumName = destAlbumName;
-        mObjectsToImport = objectsToImport;
-        mDevice = device;
-        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
-        mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAKELOCK_LABEL);
-    }
-
-    public void setListener(Listener listener) {
-        mListener = listener;
-    }
-
-    @Override
-    public void run() {
-        mWakeLock.acquire();
-        try {
-            List<MtpObjectInfo> objectsNotImported = new LinkedList<MtpObjectInfo>();
-            int visited = 0;
-            int total = mObjectsToImport.size();
-            mListener.onImportProgress(visited, total, null);
-            File dest = new File(Environment.getExternalStorageDirectory(), mDestAlbumName);
-            dest.mkdirs();
-            for (MtpObjectInfo object : mObjectsToImport) {
-                visited++;
-                String importedPath = null;
-                if (GalleryUtils.hasSpaceForSize(object.getCompressedSize())) {
-                    importedPath = new File(dest, object.getName()).getAbsolutePath();
-                    if (!mDevice.importFile(object.getObjectHandle(), importedPath)) {
-                        importedPath = null;
-                    }
-                }
-                if (importedPath == null) {
-                    objectsNotImported.add(object);
-                }
-                if (mListener != null) {
-                    mListener.onImportProgress(visited, total, importedPath);
-                }
-            }
-            if (mListener != null) {
-                mListener.onImportFinish(objectsNotImported, visited);
-            }
-        } finally {
-            mListener = null;
-            mWakeLock.release();
-        }
-    }
-}
diff --git a/src/com/android/gallery3d/ingest/IngestActivity.java b/src/com/android/gallery3d/ingest/IngestActivity.java
index 687e9fd..46173d6 100644
--- a/src/com/android/gallery3d/ingest/IngestActivity.java
+++ b/src/com/android/gallery3d/ingest/IngestActivity.java
@@ -16,6 +16,19 @@
 
 package com.android.gallery3d.ingest;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.adapter.CheckBroker;
+import com.android.gallery3d.ingest.adapter.MtpAdapter;
+import com.android.gallery3d.ingest.adapter.MtpPagerAdapter;
+import com.android.gallery3d.ingest.data.ImportTask;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex;
+import com.android.gallery3d.ingest.ui.DateTileView;
+import com.android.gallery3d.ingest.ui.IngestGridView;
+import com.android.gallery3d.ingest.ui.IngestGridView.OnClearChoicesListener;
+
+import android.annotation.TargetApi;
 import android.app.Activity;
 import android.app.ProgressDialog;
 import android.content.ComponentName;
@@ -24,7 +37,7 @@
 import android.content.ServiceConnection;
 import android.content.res.Configuration;
 import android.database.DataSetObserver;
-import android.mtp.MtpObjectInfo;
+import android.os.Build;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.IBinder;
@@ -41,530 +54,559 @@
 import android.widget.AdapterView.OnItemClickListener;
 import android.widget.TextView;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.adapter.CheckBroker;
-import com.android.gallery3d.ingest.adapter.MtpAdapter;
-import com.android.gallery3d.ingest.adapter.MtpPagerAdapter;
-import com.android.gallery3d.ingest.data.MtpBitmapFetch;
-import com.android.gallery3d.ingest.ui.DateTileView;
-import com.android.gallery3d.ingest.ui.IngestGridView;
-import com.android.gallery3d.ingest.ui.IngestGridView.OnClearChoicesListener;
-
 import java.lang.ref.WeakReference;
 import java.util.Collection;
 
+/**
+ * MTP importer, main activity.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class IngestActivity extends Activity implements
-        MtpDeviceIndex.ProgressListener, ImportTask.Listener {
+    MtpDeviceIndex.ProgressListener, ImportTask.Listener {
 
-    private IngestService mHelperService;
-    private boolean mActive = false;
-    private IngestGridView mGridView;
-    private MtpAdapter mAdapter;
-    private Handler mHandler;
-    private ProgressDialog mProgressDialog;
-    private ActionMode mActiveActionMode;
+  private IngestService mHelperService;
+  private boolean mActive = false;
+  private IngestGridView mGridView;
+  private MtpAdapter mAdapter;
+  private Handler mHandler;
+  private ProgressDialog mProgressDialog;
+  private ActionMode mActiveActionMode;
 
-    private View mWarningView;
-    private TextView mWarningText;
-    private int mLastCheckedPosition = 0;
+  private View mWarningView;
+  private TextView mWarningText;
+  private int mLastCheckedPosition = 0;
 
-    private ViewPager mFullscreenPager;
-    private MtpPagerAdapter mPagerAdapter;
-    private boolean mFullscreenPagerVisible = false;
+  private ViewPager mFullscreenPager;
+  private MtpPagerAdapter mPagerAdapter;
+  private boolean mFullscreenPagerVisible = false;
 
-    private MenuItem mMenuSwitcherItem;
-    private MenuItem mActionMenuSwitcherItem;
+  private MenuItem mMenuSwitcherItem;
+  private MenuItem mActionMenuSwitcherItem;
 
-    // The MTP framework components don't give us fine-grained file copy
-    // progress updates, so for large photos and videos, we will be stuck
-    // with a dialog not updating for a long time. To give the user feedback,
-    // we switch to the animated indeterminate progress bar after the timeout
-    // specified by INDETERMINATE_SWITCH_TIMEOUT_MS. On the next update from
-    // the framework, we switch back to the normal progress bar.
-    private static final int INDETERMINATE_SWITCH_TIMEOUT_MS = 3000;
+  // The MTP framework components don't give us fine-grained file copy
+  // progress updates, so for large photos and videos, we will be stuck
+  // with a dialog not updating for a long time. To give the user feedback,
+  // we switch to the animated indeterminate progress bar after the timeout
+  // specified by INDETERMINATE_SWITCH_TIMEOUT_MS. On the next update from
+  // the framework, we switch back to the normal progress bar.
+  private static final int INDETERMINATE_SWITCH_TIMEOUT_MS = 3000;
 
+  @Override
+  protected void onCreate(Bundle savedInstanceState) {
+    super.onCreate(savedInstanceState);
+    doBindHelperService();
+
+    setContentView(R.layout.ingest_activity_item_list);
+    mGridView = (IngestGridView) findViewById(R.id.ingest_gridview);
+    mAdapter = new MtpAdapter(this);
+    mAdapter.registerDataSetObserver(mMasterObserver);
+    mGridView.setAdapter(mAdapter);
+    mGridView.setMultiChoiceModeListener(mMultiChoiceModeListener);
+    mGridView.setOnItemClickListener(mOnItemClickListener);
+    mGridView.setOnClearChoicesListener(mPositionMappingCheckBroker);
+
+    mFullscreenPager = (ViewPager) findViewById(R.id.ingest_view_pager);
+
+    mHandler = new ItemListHandler(this);
+
+    MtpBitmapFetch.configureForContext(this);
+  }
+
+  private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
     @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        doBindHelperService();
-
-        setContentView(R.layout.ingest_activity_item_list);
-        mGridView = (IngestGridView) findViewById(R.id.ingest_gridview);
-        mAdapter = new MtpAdapter(this);
-        mAdapter.registerDataSetObserver(mMasterObserver);
-        mGridView.setAdapter(mAdapter);
-        mGridView.setMultiChoiceModeListener(mMultiChoiceModeListener);
-        mGridView.setOnItemClickListener(mOnItemClickListener);
-        mGridView.setOnClearChoicesListener(mPositionMappingCheckBroker);
-
-        mFullscreenPager = (ViewPager) findViewById(R.id.ingest_view_pager);
-
-        mHandler = new ItemListHandler(this);
-
-        MtpBitmapFetch.configureForContext(this);
+    public void onItemClick(AdapterView<?> adapterView, View itemView, int position,
+        long arg3) {
+      mLastCheckedPosition = position;
+      mGridView.setItemChecked(position, !mGridView.getCheckedItemPositions().get(position));
     }
+  };
 
-    private OnItemClickListener mOnItemClickListener = new OnItemClickListener() {
-        @Override
-        public void onItemClick(AdapterView<?> adapterView, View itemView, int position, long arg3) {
-            mLastCheckedPosition = position;
-            mGridView.setItemChecked(position, !mGridView.getCheckedItemPositions().get(position));
-        }
-    };
+  private MultiChoiceModeListener mMultiChoiceModeListener = new MultiChoiceModeListener() {
+    private boolean mIgnoreItemCheckedStateChanges = false;
 
-    private MultiChoiceModeListener mMultiChoiceModeListener = new MultiChoiceModeListener() {
-        private boolean mIgnoreItemCheckedStateChanges = false;
-
-        private void updateSelectedTitle(ActionMode mode) {
-            int count = mGridView.getCheckedItemCount();
-            mode.setTitle(getResources().getQuantityString(
-                    R.plurals.number_of_items_selected, count, count));
-        }
-
-        @Override
-        public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
-                boolean checked) {
-            if (mIgnoreItemCheckedStateChanges) return;
-            if (mAdapter.itemAtPositionIsBucket(position)) {
-                SparseBooleanArray checkedItems = mGridView.getCheckedItemPositions();
-                mIgnoreItemCheckedStateChanges = true;
-                mGridView.setItemChecked(position, false);
-
-                // Takes advantage of the fact that SectionIndexer imposes the
-                // need to clamp to the valid range
-                int nextSectionStart = mAdapter.getPositionForSection(
-                        mAdapter.getSectionForPosition(position) + 1);
-                if (nextSectionStart == position)
-                    nextSectionStart = mAdapter.getCount();
-
-                boolean rangeValue = false; // Value we want to set all of the bucket items to
-
-                // Determine if all the items in the bucket are currently checked, so that we
-                // can uncheck them, otherwise we will check all items in the bucket.
-                for (int i = position + 1; i < nextSectionStart; i++) {
-                    if (checkedItems.get(i) == false) {
-                        rangeValue = true;
-                        break;
-                    }
-                }
-
-                // Set all items in the bucket to the desired state
-                for (int i = position + 1; i < nextSectionStart; i++) {
-                    if (checkedItems.get(i) != rangeValue)
-                        mGridView.setItemChecked(i, rangeValue);
-                }
-
-                mPositionMappingCheckBroker.onBulkCheckedChange();
-                mIgnoreItemCheckedStateChanges = false;
-            } else {
-                mPositionMappingCheckBroker.onCheckedChange(position, checked);
-            }
-            mLastCheckedPosition = position;
-            updateSelectedTitle(mode);
-        }
-
-        @Override
-        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
-            return onOptionsItemSelected(item);
-        }
-
-        @Override
-        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
-            MenuInflater inflater = mode.getMenuInflater();
-            inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
-            updateSelectedTitle(mode);
-            mActiveActionMode = mode;
-            mActionMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
-            setSwitcherMenuState(mActionMenuSwitcherItem, mFullscreenPagerVisible);
-            return true;
-        }
-
-        @Override
-        public void onDestroyActionMode(ActionMode mode) {
-            mActiveActionMode = null;
-            mActionMenuSwitcherItem = null;
-            mHandler.sendEmptyMessage(ItemListHandler.MSG_BULK_CHECKED_CHANGE);
-        }
-
-        @Override
-        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
-            updateSelectedTitle(mode);
-            return false;
-        }
-    };
-
-    public boolean onOptionsItemSelected(MenuItem item) {
-        switch (item.getItemId()) {
-            case R.id.import_items:
-                if (mActiveActionMode != null) {
-                    mHelperService.importSelectedItems(
-                            mGridView.getCheckedItemPositions(),
-                            mAdapter);
-                    mActiveActionMode.finish();
-                }
-                return true;
-            case R.id.ingest_switch_view:
-                setFullscreenPagerVisibility(!mFullscreenPagerVisible);
-                return true;
-            default:
-                return false;
-        }
+    private void updateSelectedTitle(ActionMode mode) {
+      int count = mGridView.getCheckedItemCount();
+      mode.setTitle(getResources().getQuantityString(
+          R.plurals.ingest_number_of_items_selected, count, count));
     }
 
     @Override
-    public boolean onCreateOptionsMenu(Menu menu) {
-        MenuInflater inflater = getMenuInflater();
-        inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
-        mMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
-        menu.findItem(R.id.import_items).setVisible(false);
-        setSwitcherMenuState(mMenuSwitcherItem, mFullscreenPagerVisible);
-        return true;
+    public void onItemCheckedStateChanged(ActionMode mode, int position, long id,
+        boolean checked) {
+      if (mIgnoreItemCheckedStateChanges) {
+        return;
+      }
+      if (mAdapter.itemAtPositionIsBucket(position)) {
+        SparseBooleanArray checkedItems = mGridView.getCheckedItemPositions();
+        mIgnoreItemCheckedStateChanges = true;
+        mGridView.setItemChecked(position, false);
+
+        // Takes advantage of the fact that SectionIndexer imposes the
+        // need to clamp to the valid range
+        int nextSectionStart = mAdapter.getPositionForSection(
+            mAdapter.getSectionForPosition(position) + 1);
+        if (nextSectionStart == position) {
+          nextSectionStart = mAdapter.getCount();
+        }
+
+        boolean rangeValue = false; // Value we want to set all of the bucket items to
+
+        // Determine if all the items in the bucket are currently checked, so that we
+        // can uncheck them, otherwise we will check all items in the bucket.
+        for (int i = position + 1; i < nextSectionStart; i++) {
+          if (!checkedItems.get(i)) {
+            rangeValue = true;
+            break;
+          }
+        }
+
+        // Set all items in the bucket to the desired state
+        for (int i = position + 1; i < nextSectionStart; i++) {
+          if (checkedItems.get(i) != rangeValue) {
+            mGridView.setItemChecked(i, rangeValue);
+          }
+        }
+
+        mPositionMappingCheckBroker.onBulkCheckedChange();
+        mIgnoreItemCheckedStateChanges = false;
+      } else {
+        mPositionMappingCheckBroker.onCheckedChange(position, checked);
+      }
+      mLastCheckedPosition = position;
+      updateSelectedTitle(mode);
     }
 
     @Override
-    protected void onDestroy() {
-        super.onDestroy();
-        doUnbindHelperService();
+    public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
+      return onOptionsItemSelected(item);
     }
 
     @Override
-    protected void onResume() {
-        DateTileView.refreshLocale();
-        mActive = true;
-        if (mHelperService != null) mHelperService.setClientActivity(this);
-        updateWarningView();
-        super.onResume();
+    public boolean onCreateActionMode(ActionMode mode, Menu menu) {
+      MenuInflater inflater = mode.getMenuInflater();
+      inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
+      updateSelectedTitle(mode);
+      mActiveActionMode = mode;
+      mActionMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
+      setSwitcherMenuState(mActionMenuSwitcherItem, mFullscreenPagerVisible);
+      return true;
     }
 
     @Override
-    protected void onPause() {
-        if (mHelperService != null) mHelperService.setClientActivity(null);
-        mActive = false;
-        cleanupProgressDialog();
-        super.onPause();
+    public void onDestroyActionMode(ActionMode mode) {
+      mActiveActionMode = null;
+      mActionMenuSwitcherItem = null;
+      mHandler.sendEmptyMessage(ItemListHandler.MSG_BULK_CHECKED_CHANGE);
     }
 
     @Override
-    public void onConfigurationChanged(Configuration newConfig) {
-        super.onConfigurationChanged(newConfig);
-        MtpBitmapFetch.configureForContext(this);
+    public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
+      updateSelectedTitle(mode);
+      return false;
+    }
+  };
+
+  @Override
+  public boolean onOptionsItemSelected(MenuItem item) {
+    int id = item.getItemId();
+    if (id == R.id.ingest_import_items) {
+      if (mActiveActionMode != null) {
+        mHelperService.importSelectedItems(
+            mGridView.getCheckedItemPositions(),
+            mAdapter);
+        mActiveActionMode.finish();
+      }
+      return true;
+    } else if (id == R.id.ingest_switch_view) {
+      setFullscreenPagerVisibility(!mFullscreenPagerVisible);
+      return true;
+    } else {
+      return false;
+    }
+  }
+
+  @Override
+  public boolean onCreateOptionsMenu(Menu menu) {
+    MenuInflater inflater = getMenuInflater();
+    inflater.inflate(R.menu.ingest_menu_item_list_selection, menu);
+    mMenuSwitcherItem = menu.findItem(R.id.ingest_switch_view);
+    menu.findItem(R.id.ingest_import_items).setVisible(false);
+    setSwitcherMenuState(mMenuSwitcherItem, mFullscreenPagerVisible);
+    return true;
+  }
+
+  @Override
+  protected void onDestroy() {
+    doUnbindHelperService();
+    super.onDestroy();
+  }
+
+  @Override
+  protected void onResume() {
+    DateTileView.refreshLocale();
+    mActive = true;
+    if (mHelperService != null) {
+      mHelperService.setClientActivity(this);
+    }
+    updateWarningView();
+    super.onResume();
+  }
+
+  @Override
+  protected void onPause() {
+    if (mHelperService != null) {
+      mHelperService.setClientActivity(null);
+    }
+    mActive = false;
+    cleanupProgressDialog();
+    super.onPause();
+  }
+
+  @Override
+  public void onConfigurationChanged(Configuration newConfig) {
+    super.onConfigurationChanged(newConfig);
+    MtpBitmapFetch.configureForContext(this);
+  }
+
+  private void showWarningView(int textResId) {
+    if (mWarningView == null) {
+      mWarningView = findViewById(R.id.ingest_warning_view);
+      mWarningText =
+          (TextView) mWarningView.findViewById(R.id.ingest_warning_view_text);
+    }
+    mWarningText.setText(textResId);
+    mWarningView.setVisibility(View.VISIBLE);
+    setFullscreenPagerVisibility(false);
+    mGridView.setVisibility(View.GONE);
+    setSwitcherMenuVisibility(false);
+  }
+
+  private void hideWarningView() {
+    if (mWarningView != null) {
+      mWarningView.setVisibility(View.GONE);
+      setFullscreenPagerVisibility(false);
+    }
+    setSwitcherMenuVisibility(true);
+  }
+
+  private PositionMappingCheckBroker mPositionMappingCheckBroker =
+      new PositionMappingCheckBroker();
+
+  private class PositionMappingCheckBroker extends CheckBroker
+      implements OnClearChoicesListener {
+    private int mLastMappingPager = -1;
+    private int mLastMappingGrid = -1;
+
+    private int mapPagerToGridPosition(int position) {
+      if (position != mLastMappingPager) {
+        mLastMappingPager = position;
+        mLastMappingGrid = mAdapter.translatePositionWithoutLabels(position);
+      }
+      return mLastMappingGrid;
     }
 
-    private void showWarningView(int textResId) {
-        if (mWarningView == null) {
-            mWarningView = findViewById(R.id.ingest_warning_view);
-            mWarningText =
-                    (TextView)mWarningView.findViewById(R.id.ingest_warning_view_text);
-        }
-        mWarningText.setText(textResId);
-        mWarningView.setVisibility(View.VISIBLE);
-        setFullscreenPagerVisibility(false);
-        mGridView.setVisibility(View.GONE);
-    }
-
-    private void hideWarningView() {
-        if (mWarningView != null) {
-            mWarningView.setVisibility(View.GONE);
-            setFullscreenPagerVisibility(false);
-        }
-    }
-
-    private PositionMappingCheckBroker mPositionMappingCheckBroker = new PositionMappingCheckBroker();
-
-    private class PositionMappingCheckBroker extends CheckBroker
-        implements OnClearChoicesListener {
-        private int mLastMappingPager = -1;
-        private int mLastMappingGrid = -1;
-
-        private int mapPagerToGridPosition(int position) {
-            if (position != mLastMappingPager) {
-               mLastMappingPager = position;
-               mLastMappingGrid = mAdapter.translatePositionWithoutLabels(position);
-            }
-            return mLastMappingGrid;
-        }
-
-        private int mapGridToPagerPosition(int position) {
-            if (position != mLastMappingGrid) {
-                mLastMappingGrid = position;
-                mLastMappingPager = mPagerAdapter.translatePositionWithLabels(position);
-            }
-            return mLastMappingPager;
-        }
-
-        @Override
-        public void setItemChecked(int position, boolean checked) {
-            mGridView.setItemChecked(mapPagerToGridPosition(position), checked);
-        }
-
-        @Override
-        public void onCheckedChange(int position, boolean checked) {
-            if (mPagerAdapter != null) {
-                super.onCheckedChange(mapGridToPagerPosition(position), checked);
-            }
-        }
-
-        @Override
-        public boolean isItemChecked(int position) {
-            return mGridView.getCheckedItemPositions().get(mapPagerToGridPosition(position));
-        }
-
-        @Override
-        public void onClearChoices() {
-            onBulkCheckedChange();
-        }
-    };
-
-    private DataSetObserver mMasterObserver = new DataSetObserver() {
-        @Override
-        public void onChanged() {
-            if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged();
-        }
-
-        @Override
-        public void onInvalidated() {
-            if (mPagerAdapter != null) mPagerAdapter.notifyDataSetChanged();
-        }
-    };
-
-    private int pickFullscreenStartingPosition() {
-        int firstVisiblePosition = mGridView.getFirstVisiblePosition();
-        if (mLastCheckedPosition <= firstVisiblePosition
-                || mLastCheckedPosition > mGridView.getLastVisiblePosition()) {
-            return firstVisiblePosition;
-        } else {
-            return mLastCheckedPosition;
-        }
-    }
-
-    private void setSwitcherMenuState(MenuItem menuItem, boolean inFullscreenMode) {
-        if (menuItem == null) return;
-        if (!inFullscreenMode) {
-            menuItem.setIcon(android.R.drawable.ic_menu_zoom);
-            menuItem.setTitle(R.string.switch_photo_fullscreen);
-        } else {
-            menuItem.setIcon(android.R.drawable.ic_dialog_dialer);
-            menuItem.setTitle(R.string.switch_photo_grid);
-        }
-    }
-
-    private void setFullscreenPagerVisibility(boolean visible) {
-        mFullscreenPagerVisible = visible;
-        if (visible) {
-            if (mPagerAdapter == null) {
-                mPagerAdapter = new MtpPagerAdapter(this, mPositionMappingCheckBroker);
-                mPagerAdapter.setMtpDeviceIndex(mAdapter.getMtpDeviceIndex());
-            }
-            mFullscreenPager.setAdapter(mPagerAdapter);
-            mFullscreenPager.setCurrentItem(mPagerAdapter.translatePositionWithLabels(
-                    pickFullscreenStartingPosition()), false);
-        } else if (mPagerAdapter != null) {
-            mGridView.setSelection(mAdapter.translatePositionWithoutLabels(
-                    mFullscreenPager.getCurrentItem()));
-            mFullscreenPager.setAdapter(null);
-        }
-        mGridView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE);
-        mFullscreenPager.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
-        if (mActionMenuSwitcherItem != null) {
-            setSwitcherMenuState(mActionMenuSwitcherItem, visible);
-        }
-        setSwitcherMenuState(mMenuSwitcherItem, visible);
-    }
-
-    private void updateWarningView() {
-        if (!mAdapter.deviceConnected()) {
-            showWarningView(R.string.ingest_no_device);
-        } else if (mAdapter.indexReady() && mAdapter.getCount() == 0) {
-            showWarningView(R.string.ingest_empty_device);
-        } else {
-            hideWarningView();
-        }
-    }
-
-    private void UiThreadNotifyIndexChanged() {
-        mAdapter.notifyDataSetChanged();
-        if (mActiveActionMode != null) {
-            mActiveActionMode.finish();
-            mActiveActionMode = null;
-        }
-        updateWarningView();
-    }
-
-    protected void notifyIndexChanged() {
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED);
-    }
-
-    private static class ProgressState {
-        String message;
-        String title;
-        int current;
-        int max;
-
-        public void reset() {
-            title = null;
-            message = null;
-            current = 0;
-            max = 0;
-        }
-    }
-
-    private ProgressState mProgressState = new ProgressState();
-
-    @Override
-    public void onObjectIndexed(MtpObjectInfo object, int numVisited) {
-        // Not guaranteed to be called on the UI thread
-        mProgressState.reset();
-        mProgressState.max = 0;
-        mProgressState.message = getResources().getQuantityString(
-                R.plurals.ingest_number_of_items_scanned, numVisited, numVisited);
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
+    private int mapGridToPagerPosition(int position) {
+      if (position != mLastMappingGrid) {
+        mLastMappingGrid = position;
+        mLastMappingPager = mPagerAdapter.translatePositionWithLabels(position);
+      }
+      return mLastMappingPager;
     }
 
     @Override
-    public void onSorting() {
-        // Not guaranteed to be called on the UI thread
-        mProgressState.reset();
-        mProgressState.max = 0;
-        mProgressState.message = getResources().getString(R.string.ingest_sorting);
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
+    public void setItemChecked(int position, boolean checked) {
+      mGridView.setItemChecked(mapPagerToGridPosition(position), checked);
     }
 
     @Override
-    public void onIndexFinish() {
-        // Not guaranteed to be called on the UI thread
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE);
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED);
+    public void onCheckedChange(int position, boolean checked) {
+      if (mPagerAdapter != null) {
+        super.onCheckedChange(mapGridToPagerPosition(position), checked);
+      }
     }
 
     @Override
-    public void onImportProgress(final int visitedCount, final int totalCount,
-            String pathIfSuccessful) {
-        // Not guaranteed to be called on the UI thread
-        mProgressState.reset();
-        mProgressState.max = totalCount;
-        mProgressState.current = visitedCount;
-        mProgressState.title = getResources().getString(R.string.ingest_importing);
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
-        mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE);
-        mHandler.sendEmptyMessageDelayed(ItemListHandler.MSG_PROGRESS_INDETERMINATE,
-                INDETERMINATE_SWITCH_TIMEOUT_MS);
+    public boolean isItemChecked(int position) {
+      return mGridView.getCheckedItemPositions().get(mapPagerToGridPosition(position));
     }
 
     @Override
-    public void onImportFinish(Collection<MtpObjectInfo> objectsNotImported,
-            int numVisited) {
-        // Not guaranteed to be called on the UI thread
-        mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE);
-        mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE);
-        // TODO: maybe show an extra dialog listing the ones that failed
-        // importing, if any?
+    public void onClearChoices() {
+      onBulkCheckedChange();
+    }
+  }
+
+  private DataSetObserver mMasterObserver = new DataSetObserver() {
+    @Override
+    public void onChanged() {
+      if (mPagerAdapter != null) {
+        mPagerAdapter.notifyDataSetChanged();
+      }
     }
 
-    private ProgressDialog getProgressDialog() {
-        if (mProgressDialog == null || !mProgressDialog.isShowing()) {
-            mProgressDialog = new ProgressDialog(this);
-            mProgressDialog.setCancelable(false);
-        }
-        return mProgressDialog;
+    @Override
+    public void onInvalidated() {
+      if (mPagerAdapter != null) {
+        mPagerAdapter.notifyDataSetChanged();
+      }
+    }
+  };
+
+  private int pickFullscreenStartingPosition() {
+    int firstVisiblePosition = mGridView.getFirstVisiblePosition();
+    if (mLastCheckedPosition <= firstVisiblePosition
+        || mLastCheckedPosition > mGridView.getLastVisiblePosition()) {
+      return firstVisiblePosition;
+    } else {
+      return mLastCheckedPosition;
+    }
+  }
+
+  private void setSwitcherMenuState(MenuItem menuItem, boolean inFullscreenMode) {
+    if (menuItem == null) {
+      return;
+    }
+    if (!inFullscreenMode) {
+      menuItem.setIcon(android.R.drawable.ic_menu_zoom);
+      menuItem.setTitle(R.string.ingest_switch_photo_fullscreen);
+    } else {
+      menuItem.setIcon(android.R.drawable.ic_dialog_dialer);
+      menuItem.setTitle(R.string.ingest_switch_photo_grid);
+    }
+  }
+
+  private void setFullscreenPagerVisibility(boolean visible) {
+    mFullscreenPagerVisible = visible;
+    if (visible) {
+      if (mPagerAdapter == null) {
+        mPagerAdapter = new MtpPagerAdapter(this, mPositionMappingCheckBroker);
+        mPagerAdapter.setMtpDeviceIndex(mAdapter.getMtpDeviceIndex());
+      }
+      mFullscreenPager.setAdapter(mPagerAdapter);
+      mFullscreenPager.setCurrentItem(mPagerAdapter.translatePositionWithLabels(
+          pickFullscreenStartingPosition()), false);
+    } else if (mPagerAdapter != null) {
+      mGridView.setSelection(mAdapter.translatePositionWithoutLabels(
+          mFullscreenPager.getCurrentItem()));
+      mFullscreenPager.setAdapter(null);
+    }
+    mGridView.setVisibility(visible ? View.INVISIBLE : View.VISIBLE);
+    mFullscreenPager.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+    if (mActionMenuSwitcherItem != null) {
+      setSwitcherMenuState(mActionMenuSwitcherItem, visible);
+    }
+    setSwitcherMenuState(mMenuSwitcherItem, visible);
+  }
+
+  private void setSwitcherMenuVisibility(boolean visible) {
+    if (mActionMenuSwitcherItem != null) {
+      mActionMenuSwitcherItem.setVisible(visible);
+    }
+    if (mMenuSwitcherItem != null) {
+      mMenuSwitcherItem.setVisible(visible);
+    }
+  }
+
+  private void updateWarningView() {
+    if (!mAdapter.deviceConnected()) {
+      showWarningView(R.string.ingest_no_device);
+    } else if (mAdapter.indexReady() && mAdapter.getCount() == 0) {
+      showWarningView(R.string.ingest_empty_device);
+    } else {
+      hideWarningView();
+    }
+  }
+
+  private void uiThreadNotifyIndexChanged() {
+    mAdapter.notifyDataSetChanged();
+    if (mActiveActionMode != null) {
+      mActiveActionMode.finish();
+      mActiveActionMode = null;
+    }
+    updateWarningView();
+  }
+
+  protected void notifyIndexChanged() {
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED);
+  }
+
+  private static class ProgressState {
+    String message;
+    String title;
+    int current;
+    int max;
+
+    public void reset() {
+      title = null;
+      message = null;
+      current = 0;
+      max = 0;
+    }
+  }
+
+  private ProgressState mProgressState = new ProgressState();
+
+  @Override
+  public void onObjectIndexed(IngestObjectInfo object, int numVisited) {
+    // Not guaranteed to be called on the UI thread
+    mProgressState.reset();
+    mProgressState.max = 0;
+    mProgressState.message = getResources().getQuantityString(
+        R.plurals.ingest_number_of_items_scanned, numVisited, numVisited);
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
+  }
+
+  @Override
+  public void onSortingStarted() {
+    // Not guaranteed to be called on the UI thread
+    mProgressState.reset();
+    mProgressState.max = 0;
+    mProgressState.message = getResources().getString(R.string.ingest_sorting);
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
+  }
+
+  @Override
+  public void onIndexingFinished() {
+    // Not guaranteed to be called on the UI thread
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE);
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_NOTIFY_CHANGED);
+  }
+
+  @Override
+  public void onImportProgress(final int visitedCount, final int totalCount,
+      String pathIfSuccessful) {
+    // Not guaranteed to be called on the UI thread
+    mProgressState.reset();
+    mProgressState.max = totalCount;
+    mProgressState.current = visitedCount;
+    mProgressState.title = getResources().getString(R.string.ingest_importing);
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_UPDATE);
+    mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE);
+    mHandler.sendEmptyMessageDelayed(ItemListHandler.MSG_PROGRESS_INDETERMINATE,
+        INDETERMINATE_SWITCH_TIMEOUT_MS);
+  }
+
+  @Override
+  public void onImportFinish(Collection<IngestObjectInfo> objectsNotImported,
+      int numVisited) {
+    // Not guaranteed to be called on the UI thread
+    mHandler.sendEmptyMessage(ItemListHandler.MSG_PROGRESS_HIDE);
+    mHandler.removeMessages(ItemListHandler.MSG_PROGRESS_INDETERMINATE);
+    // TODO(georgescu): maybe show an extra dialog listing the ones that failed
+    // importing, if any?
+  }
+
+  private ProgressDialog getProgressDialog() {
+    if (mProgressDialog == null || !mProgressDialog.isShowing()) {
+      mProgressDialog = new ProgressDialog(this);
+      mProgressDialog.setCancelable(false);
+    }
+    return mProgressDialog;
+  }
+
+  private void updateProgressDialog() {
+    ProgressDialog dialog = getProgressDialog();
+    boolean indeterminate = (mProgressState.max == 0);
+    dialog.setIndeterminate(indeterminate);
+    dialog.setProgressStyle(indeterminate ? ProgressDialog.STYLE_SPINNER
+        : ProgressDialog.STYLE_HORIZONTAL);
+    if (mProgressState.title != null) {
+      dialog.setTitle(mProgressState.title);
+    }
+    if (mProgressState.message != null) {
+      dialog.setMessage(mProgressState.message);
+    }
+    if (!indeterminate) {
+      dialog.setProgress(mProgressState.current);
+      dialog.setMax(mProgressState.max);
+    }
+    if (!dialog.isShowing()) {
+      dialog.show();
+    }
+  }
+
+  private void makeProgressDialogIndeterminate() {
+    ProgressDialog dialog = getProgressDialog();
+    dialog.setIndeterminate(true);
+  }
+
+  private void cleanupProgressDialog() {
+    if (mProgressDialog != null) {
+      mProgressDialog.dismiss();
+      mProgressDialog = null;
+    }
+  }
+
+  // This is static and uses a WeakReference in order to avoid leaking the Activity
+  private static class ItemListHandler extends Handler {
+    public static final int MSG_PROGRESS_UPDATE = 0;
+    public static final int MSG_PROGRESS_HIDE = 1;
+    public static final int MSG_NOTIFY_CHANGED = 2;
+    public static final int MSG_BULK_CHECKED_CHANGE = 3;
+    public static final int MSG_PROGRESS_INDETERMINATE = 4;
+
+    WeakReference<IngestActivity> mParentReference;
+
+    public ItemListHandler(IngestActivity parent) {
+      super();
+      mParentReference = new WeakReference<IngestActivity>(parent);
     }
 
-    private void updateProgressDialog() {
-        ProgressDialog dialog = getProgressDialog();
-        boolean indeterminate = (mProgressState.max == 0);
-        dialog.setIndeterminate(indeterminate);
-        dialog.setProgressStyle(indeterminate ? ProgressDialog.STYLE_SPINNER
-                : ProgressDialog.STYLE_HORIZONTAL);
-        if (mProgressState.title != null) {
-            dialog.setTitle(mProgressState.title);
-        }
-        if (mProgressState.message != null) {
-            dialog.setMessage(mProgressState.message);
-        }
-        if (!indeterminate) {
-            dialog.setProgress(mProgressState.current);
-            dialog.setMax(mProgressState.max);
-        }
-        if (!dialog.isShowing()) {
-            dialog.show();
-        }
+    @Override
+    public void handleMessage(Message message) {
+      IngestActivity parent = mParentReference.get();
+      if (parent == null || !parent.mActive) {
+        return;
+      }
+      switch (message.what) {
+        case MSG_PROGRESS_HIDE:
+          parent.cleanupProgressDialog();
+          break;
+        case MSG_PROGRESS_UPDATE:
+          parent.updateProgressDialog();
+          break;
+        case MSG_NOTIFY_CHANGED:
+          parent.uiThreadNotifyIndexChanged();
+          break;
+        case MSG_BULK_CHECKED_CHANGE:
+          parent.mPositionMappingCheckBroker.onBulkCheckedChange();
+          break;
+        case MSG_PROGRESS_INDETERMINATE:
+          parent.makeProgressDialogIndeterminate();
+          break;
+        default:
+          break;
+      }
+    }
+  }
+
+  private ServiceConnection mHelperServiceConnection = new ServiceConnection() {
+    @Override
+    public void onServiceConnected(ComponentName className, IBinder service) {
+      mHelperService = ((IngestService.LocalBinder) service).getService();
+      mHelperService.setClientActivity(IngestActivity.this);
+      MtpDeviceIndex index = mHelperService.getIndex();
+      mAdapter.setMtpDeviceIndex(index);
+      if (mPagerAdapter != null) {
+        mPagerAdapter.setMtpDeviceIndex(index);
+      }
     }
 
-    private void makeProgressDialogIndeterminate() {
-        ProgressDialog dialog = getProgressDialog();
-        dialog.setIndeterminate(true);
+    @Override
+    public void onServiceDisconnected(ComponentName className) {
+      mHelperService = null;
     }
+  };
 
-    private void cleanupProgressDialog() {
-        if (mProgressDialog != null) {
-            mProgressDialog.hide();
-            mProgressDialog = null;
-        }
+  private void doBindHelperService() {
+    bindService(new Intent(getApplicationContext(), IngestService.class),
+        mHelperServiceConnection, Context.BIND_AUTO_CREATE);
+  }
+
+  private void doUnbindHelperService() {
+    if (mHelperService != null) {
+      mHelperService.setClientActivity(null);
+      unbindService(mHelperServiceConnection);
     }
-
-    // This is static and uses a WeakReference in order to avoid leaking the Activity
-    private static class ItemListHandler extends Handler {
-        public static final int MSG_PROGRESS_UPDATE = 0;
-        public static final int MSG_PROGRESS_HIDE = 1;
-        public static final int MSG_NOTIFY_CHANGED = 2;
-        public static final int MSG_BULK_CHECKED_CHANGE = 3;
-        public static final int MSG_PROGRESS_INDETERMINATE = 4;
-
-        WeakReference<IngestActivity> mParentReference;
-
-        public ItemListHandler(IngestActivity parent) {
-            super();
-            mParentReference = new WeakReference<IngestActivity>(parent);
-        }
-
-        public void handleMessage(Message message) {
-            IngestActivity parent = mParentReference.get();
-            if (parent == null || !parent.mActive)
-                return;
-            switch (message.what) {
-                case MSG_PROGRESS_HIDE:
-                    parent.cleanupProgressDialog();
-                    break;
-                case MSG_PROGRESS_UPDATE:
-                    parent.updateProgressDialog();
-                    break;
-                case MSG_NOTIFY_CHANGED:
-                    parent.UiThreadNotifyIndexChanged();
-                    break;
-                case MSG_BULK_CHECKED_CHANGE:
-                    parent.mPositionMappingCheckBroker.onBulkCheckedChange();
-                    break;
-                case MSG_PROGRESS_INDETERMINATE:
-                    parent.makeProgressDialogIndeterminate();
-                    break;
-                default:
-                    break;
-            }
-        }
-    }
-
-    private ServiceConnection mHelperServiceConnection = new ServiceConnection() {
-        public void onServiceConnected(ComponentName className, IBinder service) {
-            mHelperService = ((IngestService.LocalBinder) service).getService();
-            mHelperService.setClientActivity(IngestActivity.this);
-            MtpDeviceIndex index = mHelperService.getIndex();
-            mAdapter.setMtpDeviceIndex(index);
-            if (mPagerAdapter != null) mPagerAdapter.setMtpDeviceIndex(index);
-        }
-
-        public void onServiceDisconnected(ComponentName className) {
-            mHelperService = null;
-        }
-    };
-
-    private void doBindHelperService() {
-        bindService(new Intent(getApplicationContext(), IngestService.class),
-                mHelperServiceConnection, Context.BIND_AUTO_CREATE);
-    }
-
-    private void doUnbindHelperService() {
-        if (mHelperService != null) {
-            mHelperService.setClientActivity(null);
-            unbindService(mHelperServiceConnection);
-        }
-    }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/IngestService.java b/src/com/android/gallery3d/ingest/IngestService.java
index 9d406b1..98aa7f5 100644
--- a/src/com/android/gallery3d/ingest/IngestService.java
+++ b/src/com/android/gallery3d/ingest/IngestService.java
@@ -16,6 +16,13 @@
 
 package com.android.gallery3d.ingest;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.ImportTask;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpClient;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex;
+
+import android.annotation.TargetApi;
 import android.app.NotificationManager;
 import android.app.PendingIntent;
 import android.app.Service;
@@ -25,299 +32,303 @@
 import android.media.MediaScannerConnection.MediaScannerConnectionClient;
 import android.mtp.MtpDevice;
 import android.mtp.MtpDeviceInfo;
-import android.mtp.MtpObjectInfo;
 import android.net.Uri;
 import android.os.Binder;
+import android.os.Build;
 import android.os.IBinder;
 import android.os.SystemClock;
 import android.support.v4.app.NotificationCompat;
 import android.util.SparseBooleanArray;
 import android.widget.Adapter;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.app.NotificationIds;
-import com.android.gallery3d.data.MtpClient;
-import com.android.gallery3d.util.BucketNames;
-import com.android.gallery3d.util.UsageStatistics;
-
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 
+/**
+ * Service for MTP importing tasks.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class IngestService extends Service implements ImportTask.Listener,
-        MtpDeviceIndex.ProgressListener, MtpClient.Listener {
+    MtpDeviceIndex.ProgressListener, MtpClient.Listener {
 
-    public class LocalBinder extends Binder {
-        IngestService getService() {
-            return IngestService.this;
+  /**
+   * Convenience class to allow easy access to the service instance.
+   */
+  public class LocalBinder extends Binder {
+    IngestService getService() {
+      return IngestService.this;
+    }
+  }
+
+  private static final int PROGRESS_UPDATE_INTERVAL_MS = 180;
+
+  private MtpClient mClient;
+  private final IBinder mBinder = new LocalBinder();
+  private ScannerClient mScannerClient;
+  private MtpDevice mDevice;
+  private String mDevicePrettyName;
+  private MtpDeviceIndex mIndex;
+  private IngestActivity mClientActivity;
+  private boolean mRedeliverImportFinish = false;
+  private int mRedeliverImportFinishCount = 0;
+  private Collection<IngestObjectInfo> mRedeliverObjectsNotImported;
+  private boolean mRedeliverNotifyIndexChanged = false;
+  private boolean mRedeliverIndexFinish = false;
+  private NotificationManager mNotificationManager;
+  private NotificationCompat.Builder mNotificationBuilder;
+  private long mLastProgressIndexTime = 0;
+  private boolean mNeedRelaunchNotification = false;
+
+  @Override
+  public void onCreate() {
+    super.onCreate();
+    mScannerClient = new ScannerClient(this);
+    mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
+    mNotificationBuilder = new NotificationCompat.Builder(this);
+    // TODO(georgescu): Use a better drawable for the notificaton?
+    mNotificationBuilder.setSmallIcon(android.R.drawable.stat_notify_sync)
+        .setContentIntent(PendingIntent.getActivity(this, 0,
+            new Intent(this, IngestActivity.class), 0));
+    mIndex = MtpDeviceIndex.getInstance();
+    mIndex.setProgressListener(this);
+
+    mClient = new MtpClient(getApplicationContext());
+    List<MtpDevice> devices = mClient.getDeviceList();
+    if (!devices.isEmpty()) {
+      setDevice(devices.get(0));
+    }
+    mClient.addListener(this);
+  }
+
+  @Override
+  public void onDestroy() {
+    mClient.close();
+    mIndex.unsetProgressListener(this);
+    super.onDestroy();
+  }
+
+  @Override
+  public IBinder onBind(Intent intent) {
+    return mBinder;
+  }
+
+  private void setDevice(MtpDevice device) {
+    if (mDevice == device) {
+      return;
+    }
+    mRedeliverImportFinish = false;
+    mRedeliverObjectsNotImported = null;
+    mRedeliverNotifyIndexChanged = false;
+    mRedeliverIndexFinish = false;
+    mDevice = device;
+    mIndex.setDevice(mDevice);
+    if (mDevice != null) {
+      MtpDeviceInfo deviceInfo = mDevice.getDeviceInfo();
+      if (deviceInfo == null) {
+        setDevice(null);
+        return;
+      } else {
+        mDevicePrettyName = deviceInfo.getModel();
+        mNotificationBuilder.setContentTitle(mDevicePrettyName);
+        new Thread(mIndex.getIndexRunnable()).start();
+      }
+    } else {
+      mDevicePrettyName = null;
+    }
+    if (mClientActivity != null) {
+      mClientActivity.notifyIndexChanged();
+    } else {
+      mRedeliverNotifyIndexChanged = true;
+    }
+  }
+
+  protected MtpDeviceIndex getIndex() {
+    return mIndex;
+  }
+
+  protected void setClientActivity(IngestActivity activity) {
+    if (mClientActivity == activity) {
+      return;
+    }
+    mClientActivity = activity;
+    if (mClientActivity == null) {
+      if (mNeedRelaunchNotification) {
+        mNotificationBuilder.setProgress(0, 0, false)
+            .setContentText(getResources().getText(R.string.ingest_scanning_done));
+        mNotificationManager.notify(R.id.ingest_notification_scanning,
+            mNotificationBuilder.build());
+      }
+      return;
+    }
+    mNotificationManager.cancel(R.id.ingest_notification_importing);
+    mNotificationManager.cancel(R.id.ingest_notification_scanning);
+    if (mRedeliverImportFinish) {
+      mClientActivity.onImportFinish(mRedeliverObjectsNotImported,
+          mRedeliverImportFinishCount);
+      mRedeliverImportFinish = false;
+      mRedeliverObjectsNotImported = null;
+    }
+    if (mRedeliverNotifyIndexChanged) {
+      mClientActivity.notifyIndexChanged();
+      mRedeliverNotifyIndexChanged = false;
+    }
+    if (mRedeliverIndexFinish) {
+      mClientActivity.onIndexingFinished();
+      mRedeliverIndexFinish = false;
+    }
+    if (mDevice != null) {
+      mNeedRelaunchNotification = true;
+    }
+  }
+
+  protected void importSelectedItems(SparseBooleanArray selected, Adapter adapter) {
+    List<IngestObjectInfo> importHandles = new ArrayList<IngestObjectInfo>();
+    for (int i = 0; i < selected.size(); i++) {
+      if (selected.valueAt(i)) {
+        Object item = adapter.getItem(selected.keyAt(i));
+        if (item instanceof IngestObjectInfo) {
+          importHandles.add(((IngestObjectInfo) item));
         }
+      }
+    }
+    ImportTask task = new ImportTask(mDevice, importHandles, mDevicePrettyName, this);
+    task.setListener(this);
+    mNotificationBuilder.setProgress(0, 0, true)
+        .setContentText(getResources().getText(R.string.ingest_importing));
+    startForeground(R.id.ingest_notification_importing,
+        mNotificationBuilder.build());
+    new Thread(task).start();
+  }
+
+  @Override
+  public void deviceAdded(MtpDevice device) {
+    if (mDevice == null) {
+      setDevice(device);
+    }
+  }
+
+  @Override
+  public void deviceRemoved(MtpDevice device) {
+    if (device == mDevice) {
+      mNotificationManager.cancel(R.id.ingest_notification_scanning);
+      mNotificationManager.cancel(R.id.ingest_notification_importing);
+      setDevice(null);
+      mNeedRelaunchNotification = false;
+
+    }
+  }
+
+  @Override
+  public void onImportProgress(int visitedCount, int totalCount,
+      String pathIfSuccessful) {
+    if (pathIfSuccessful != null) {
+      mScannerClient.scanPath(pathIfSuccessful);
+    }
+    mNeedRelaunchNotification = false;
+    if (mClientActivity != null) {
+      mClientActivity.onImportProgress(visitedCount, totalCount, pathIfSuccessful);
+    }
+    mNotificationBuilder.setProgress(totalCount, visitedCount, false)
+        .setContentText(getResources().getText(R.string.ingest_importing));
+    mNotificationManager.notify(R.id.ingest_notification_importing,
+        mNotificationBuilder.build());
+  }
+
+  @Override
+  public void onImportFinish(Collection<IngestObjectInfo> objectsNotImported,
+      int visitedCount) {
+    stopForeground(true);
+    mNeedRelaunchNotification = true;
+    if (mClientActivity != null) {
+      mClientActivity.onImportFinish(objectsNotImported, visitedCount);
+    } else {
+      mRedeliverImportFinish = true;
+      mRedeliverObjectsNotImported = objectsNotImported;
+      mRedeliverImportFinishCount = visitedCount;
+      mNotificationBuilder.setProgress(0, 0, false)
+          .setContentText(getResources().getText(R.string.ingest_import_complete));
+      mNotificationManager.notify(R.id.ingest_notification_importing,
+          mNotificationBuilder.build());
+    }
+  }
+
+  @Override
+  public void onObjectIndexed(IngestObjectInfo object, int numVisited) {
+    mNeedRelaunchNotification = false;
+    if (mClientActivity != null) {
+      mClientActivity.onObjectIndexed(object, numVisited);
+    } else {
+      // Throttle the updates to one every PROGRESS_UPDATE_INTERVAL_MS milliseconds
+      long currentTime = SystemClock.uptimeMillis();
+      if (currentTime > mLastProgressIndexTime + PROGRESS_UPDATE_INTERVAL_MS) {
+        mLastProgressIndexTime = currentTime;
+        mNotificationBuilder.setProgress(0, numVisited, true)
+            .setContentText(getResources().getText(R.string.ingest_scanning));
+        mNotificationManager.notify(R.id.ingest_notification_scanning,
+            mNotificationBuilder.build());
+      }
+    }
+  }
+
+  @Override
+  public void onSortingStarted() {
+    if (mClientActivity != null) {
+      mClientActivity.onSortingStarted();
+    }
+  }
+
+  @Override
+  public void onIndexingFinished() {
+    mNeedRelaunchNotification = true;
+    if (mClientActivity != null) {
+      mClientActivity.onIndexingFinished();
+    } else {
+      mNotificationBuilder.setProgress(0, 0, false)
+          .setContentText(getResources().getText(R.string.ingest_scanning_done));
+      mNotificationManager.notify(R.id.ingest_notification_scanning,
+          mNotificationBuilder.build());
+      mRedeliverIndexFinish = true;
+    }
+  }
+
+  // Copied from old Gallery3d code
+  private static final class ScannerClient implements MediaScannerConnectionClient {
+    ArrayList<String> mPaths = new ArrayList<String>();
+    MediaScannerConnection mScannerConnection;
+    boolean mConnected;
+    Object mLock = new Object();
+
+    public ScannerClient(Context context) {
+      mScannerConnection = new MediaScannerConnection(context, this);
     }
 
-    private static final int PROGRESS_UPDATE_INTERVAL_MS = 180;
-
-    private static MtpClient sClient;
-
-    private final IBinder mBinder = new LocalBinder();
-    private ScannerClient mScannerClient;
-    private MtpDevice mDevice;
-    private String mDevicePrettyName;
-    private MtpDeviceIndex mIndex;
-    private IngestActivity mClientActivity;
-    private boolean mRedeliverImportFinish = false;
-    private int mRedeliverImportFinishCount = 0;
-    private Collection<MtpObjectInfo> mRedeliverObjectsNotImported;
-    private boolean mRedeliverNotifyIndexChanged = false;
-    private boolean mRedeliverIndexFinish = false;
-    private NotificationManager mNotificationManager;
-    private NotificationCompat.Builder mNotificationBuilder;
-    private long mLastProgressIndexTime = 0;
-    private boolean mNeedRelaunchNotification = false;
-
-    @Override
-    public void onCreate() {
-        super.onCreate();
-        mScannerClient = new ScannerClient(this);
-        mNotificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
-        mNotificationBuilder = new NotificationCompat.Builder(this);
-        mNotificationBuilder.setSmallIcon(android.R.drawable.stat_notify_sync) // TODO drawable
-                .setContentIntent(PendingIntent.getActivity(this, 0, new Intent(this, IngestActivity.class), 0));
-        mIndex = MtpDeviceIndex.getInstance();
-        mIndex.setProgressListener(this);
-
-        if (sClient == null) {
-            sClient = new MtpClient(getApplicationContext());
-        }
-        List<MtpDevice> devices = sClient.getDeviceList();
-        if (devices.size() > 0) {
-            setDevice(devices.get(0));
-        }
-        sClient.addListener(this);
-    }
-
-    @Override
-    public void onDestroy() {
-        sClient.removeListener(this);
-        mIndex.unsetProgressListener(this);
-        super.onDestroy();
-    }
-
-    @Override
-    public IBinder onBind(Intent intent) {
-        return mBinder;
-    }
-
-    private void setDevice(MtpDevice device) {
-        if (mDevice == device) return;
-        mRedeliverImportFinish = false;
-        mRedeliverObjectsNotImported = null;
-        mRedeliverNotifyIndexChanged = false;
-        mRedeliverIndexFinish = false;
-        mDevice = device;
-        mIndex.setDevice(mDevice);
-        if (mDevice != null) {
-            MtpDeviceInfo deviceInfo = mDevice.getDeviceInfo();
-            if (deviceInfo == null) {
-                setDevice(null);
-                return;
-            } else {
-                mDevicePrettyName = deviceInfo.getModel();
-                mNotificationBuilder.setContentTitle(mDevicePrettyName);
-                new Thread(mIndex.getIndexRunnable()).start();
-            }
+    public void scanPath(String path) {
+      synchronized (mLock) {
+        if (mConnected) {
+          mScannerConnection.scanFile(path, null);
         } else {
-            mDevicePrettyName = null;
+          mPaths.add(path);
+          mScannerConnection.connect();
         }
-        if (mClientActivity != null) {
-            mClientActivity.notifyIndexChanged();
-        } else {
-            mRedeliverNotifyIndexChanged = true;
-        }
-    }
-
-    protected MtpDeviceIndex getIndex() {
-        return mIndex;
-    }
-
-    protected void setClientActivity(IngestActivity activity) {
-        if (mClientActivity == activity) return;
-        mClientActivity = activity;
-        if (mClientActivity == null) {
-            if (mNeedRelaunchNotification) {
-                mNotificationBuilder.setProgress(0, 0, false)
-                    .setContentText(getResources().getText(R.string.ingest_scanning_done));
-                mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
-                    mNotificationBuilder.build());
-            }
-            return;
-        }
-        mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_IMPORTING);
-        mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_SCANNING);
-        if (mRedeliverImportFinish) {
-            mClientActivity.onImportFinish(mRedeliverObjectsNotImported,
-                    mRedeliverImportFinishCount);
-            mRedeliverImportFinish = false;
-            mRedeliverObjectsNotImported = null;
-        }
-        if (mRedeliverNotifyIndexChanged) {
-            mClientActivity.notifyIndexChanged();
-            mRedeliverNotifyIndexChanged = false;
-        }
-        if (mRedeliverIndexFinish) {
-            mClientActivity.onIndexFinish();
-            mRedeliverIndexFinish = false;
-        }
-        if (mDevice != null) {
-            mNeedRelaunchNotification = true;
-        }
-    }
-
-    protected void importSelectedItems(SparseBooleanArray selected, Adapter adapter) {
-        List<MtpObjectInfo> importHandles = new ArrayList<MtpObjectInfo>();
-        for (int i = 0; i < selected.size(); i++) {
-            if (selected.valueAt(i)) {
-                Object item = adapter.getItem(selected.keyAt(i));
-                if (item instanceof MtpObjectInfo) {
-                    importHandles.add(((MtpObjectInfo) item));
-                }
-            }
-        }
-        ImportTask task = new ImportTask(mDevice, importHandles, BucketNames.IMPORTED, this);
-        task.setListener(this);
-        mNotificationBuilder.setProgress(0, 0, true)
-            .setContentText(getResources().getText(R.string.ingest_importing));
-        startForeground(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
-                    mNotificationBuilder.build());
-        new Thread(task).start();
+      }
     }
 
     @Override
-    public void deviceAdded(MtpDevice device) {
-        if (mDevice == null) {
-            setDevice(device);
-            UsageStatistics.onEvent(UsageStatistics.COMPONENT_IMPORTER,
-                    "DeviceConnected", null);
+    public void onMediaScannerConnected() {
+      synchronized (mLock) {
+        mConnected = true;
+        if (!mPaths.isEmpty()) {
+          for (String path : mPaths) {
+            mScannerConnection.scanFile(path, null);
+          }
+          mPaths.clear();
         }
+      }
     }
 
     @Override
-    public void deviceRemoved(MtpDevice device) {
-        if (device == mDevice) {
-            setDevice(null);
-            mNeedRelaunchNotification = false;
-            mNotificationManager.cancel(NotificationIds.INGEST_NOTIFICATION_SCANNING);
-        }
+    public void onScanCompleted(String path, Uri uri) {
     }
-
-    @Override
-    public void onImportProgress(int visitedCount, int totalCount,
-            String pathIfSuccessful) {
-        if (pathIfSuccessful != null) {
-            mScannerClient.scanPath(pathIfSuccessful);
-        }
-        mNeedRelaunchNotification = false;
-        if (mClientActivity != null) {
-            mClientActivity.onImportProgress(visitedCount, totalCount, pathIfSuccessful);
-        }
-        mNotificationBuilder.setProgress(totalCount, visitedCount, false)
-            .setContentText(getResources().getText(R.string.ingest_importing));
-        mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
-                mNotificationBuilder.build());
-    }
-
-    @Override
-    public void onImportFinish(Collection<MtpObjectInfo> objectsNotImported,
-            int visitedCount) {
-        stopForeground(true);
-        mNeedRelaunchNotification = true;
-        if (mClientActivity != null) {
-            mClientActivity.onImportFinish(objectsNotImported, visitedCount);
-        } else {
-            mRedeliverImportFinish = true;
-            mRedeliverObjectsNotImported = objectsNotImported;
-            mRedeliverImportFinishCount = visitedCount;
-            mNotificationBuilder.setProgress(0, 0, false)
-                .setContentText(getResources().getText(R.string.import_complete));
-            mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_IMPORTING,
-                    mNotificationBuilder.build());
-        }
-        UsageStatistics.onEvent(UsageStatistics.COMPONENT_IMPORTER,
-                "ImportFinished", null, visitedCount);
-    }
-
-    @Override
-    public void onObjectIndexed(MtpObjectInfo object, int numVisited) {
-        mNeedRelaunchNotification = false;
-        if (mClientActivity != null) {
-            mClientActivity.onObjectIndexed(object, numVisited);
-        } else {
-            // Throttle the updates to one every PROGRESS_UPDATE_INTERVAL_MS milliseconds
-            long currentTime = SystemClock.uptimeMillis();
-            if (currentTime > mLastProgressIndexTime + PROGRESS_UPDATE_INTERVAL_MS) {
-                mLastProgressIndexTime = currentTime;
-                mNotificationBuilder.setProgress(0, numVisited, true)
-                        .setContentText(getResources().getText(R.string.ingest_scanning));
-                mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
-                        mNotificationBuilder.build());
-            }
-        }
-    }
-
-    @Override
-    public void onSorting() {
-        if (mClientActivity != null) mClientActivity.onSorting();
-    }
-
-    @Override
-    public void onIndexFinish() {
-        mNeedRelaunchNotification = true;
-        if (mClientActivity != null) {
-            mClientActivity.onIndexFinish();
-        } else {
-            mNotificationBuilder.setProgress(0, 0, false)
-                .setContentText(getResources().getText(R.string.ingest_scanning_done));
-            mNotificationManager.notify(NotificationIds.INGEST_NOTIFICATION_SCANNING,
-                    mNotificationBuilder.build());
-            mRedeliverIndexFinish = true;
-        }
-    }
-
-    // Copied from old Gallery3d code
-    private static final class ScannerClient implements MediaScannerConnectionClient {
-        ArrayList<String> mPaths = new ArrayList<String>();
-        MediaScannerConnection mScannerConnection;
-        boolean mConnected;
-        Object mLock = new Object();
-
-        public ScannerClient(Context context) {
-            mScannerConnection = new MediaScannerConnection(context, this);
-        }
-
-        public void scanPath(String path) {
-            synchronized (mLock) {
-                if (mConnected) {
-                    mScannerConnection.scanFile(path, null);
-                } else {
-                    mPaths.add(path);
-                    mScannerConnection.connect();
-                }
-            }
-        }
-
-        @Override
-        public void onMediaScannerConnected() {
-            synchronized (mLock) {
-                mConnected = true;
-                if (!mPaths.isEmpty()) {
-                    for (String path : mPaths) {
-                        mScannerConnection.scanFile(path, null);
-                    }
-                    mPaths.clear();
-                }
-            }
-        }
-
-        @Override
-        public void onScanCompleted(String path, Uri uri) {
-        }
-    }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/MtpDeviceIndex.java b/src/com/android/gallery3d/ingest/MtpDeviceIndex.java
deleted file mode 100644
index fed851e..0000000
--- a/src/com/android/gallery3d/ingest/MtpDeviceIndex.java
+++ /dev/null
@@ -1,602 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ingest;
-
-import android.mtp.MtpConstants;
-import android.mtp.MtpDevice;
-import android.mtp.MtpObjectInfo;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.Stack;
-
-/**
- * MTP objects in the index are organized into "buckets," or groupings.
- * At present, these buckets are based on the date an item was created.
- *
- * When the index is created, the buckets are sorted in their natural
- * order, and the items within the buckets sorted by the date they are taken.
- *
- * The index enables the access of items and bucket labels as one unified list.
- * For example, let's say we have the following data in the index:
- *    [Bucket A]: [photo 1], [photo 2]
- *    [Bucket B]: [photo 3]
- *
- * Then the items can be thought of as being organized as a 5 element list:
- *   [Bucket A], [photo 1], [photo 2], [Bucket B], [photo 3]
- *
- * The data can also be accessed in descending order, in which case the list
- * would be a bit different from simply reversing the ascending list, since the
- * bucket labels need to always be at the beginning:
- *   [Bucket B], [photo 3], [Bucket A], [photo 2], [photo 1]
- *
- * The index enables all the following operations in constant time, both for
- * ascending and descending views of the data:
- *   - get/getAscending/getDescending: get an item at a specified list position
- *   - size: get the total number of items (bucket labels and MTP objects)
- *   - getFirstPositionForBucketNumber
- *   - getBucketNumberForPosition
- *   - isFirstInBucket
- *
- * See the comments in buildLookupIndex for implementation notes.
- */
-public class MtpDeviceIndex {
-
-    public static final int FORMAT_MOV = 0x300D; // For some reason this is not in MtpConstants
-
-    public static final Set<Integer> SUPPORTED_IMAGE_FORMATS;
-    public static final Set<Integer> SUPPORTED_VIDEO_FORMATS;
-
-    static {
-        SUPPORTED_IMAGE_FORMATS = new HashSet<Integer>();
-        SUPPORTED_IMAGE_FORMATS.add(MtpConstants.FORMAT_JFIF);
-        SUPPORTED_IMAGE_FORMATS.add(MtpConstants.FORMAT_EXIF_JPEG);
-        SUPPORTED_IMAGE_FORMATS.add(MtpConstants.FORMAT_PNG);
-        SUPPORTED_IMAGE_FORMATS.add(MtpConstants.FORMAT_GIF);
-        SUPPORTED_IMAGE_FORMATS.add(MtpConstants.FORMAT_BMP);
-
-        SUPPORTED_VIDEO_FORMATS = new HashSet<Integer>();
-        SUPPORTED_VIDEO_FORMATS.add(MtpConstants.FORMAT_3GP_CONTAINER);
-        SUPPORTED_VIDEO_FORMATS.add(MtpConstants.FORMAT_AVI);
-        SUPPORTED_VIDEO_FORMATS.add(MtpConstants.FORMAT_MP4_CONTAINER);
-        SUPPORTED_VIDEO_FORMATS.add(MtpConstants.FORMAT_MPEG);
-        // TODO: add FORMAT_MOV once Media Scanner supports .mov files
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + ((mDevice == null) ? 0 : mDevice.getDeviceId());
-        result = prime * result + mGeneration;
-        return result;
-    }
-
-    public interface ProgressListener {
-        public void onObjectIndexed(MtpObjectInfo object, int numVisited);
-
-        public void onSorting();
-
-        public void onIndexFinish();
-    }
-
-    public enum SortOrder {
-        Ascending, Descending
-    }
-
-    private MtpDevice mDevice;
-    private int[] mUnifiedLookupIndex;
-    private MtpObjectInfo[] mMtpObjects;
-    private DateBucket[] mBuckets;
-    private int mGeneration = 0;
-
-    public enum Progress {
-        Uninitialized, Initialized, Pending, Started, Sorting, Finished
-    }
-
-    private Progress mProgress = Progress.Uninitialized;
-    private ProgressListener mProgressListener;
-
-    private static final MtpDeviceIndex sInstance = new MtpDeviceIndex();
-    private static final MtpObjectTimestampComparator sMtpObjectComparator =
-            new MtpObjectTimestampComparator();
-
-    public static MtpDeviceIndex getInstance() {
-        return sInstance;
-    }
-
-    private MtpDeviceIndex() {
-    }
-
-    synchronized public MtpDevice getDevice() {
-        return mDevice;
-    }
-
-    /**
-     * Sets the MtpDevice that should be indexed and initializes state, but does
-     * not kick off the actual indexing task, which is instead done by using
-     * {@link #getIndexRunnable()}
-     *
-     * @param device The MtpDevice that should be indexed
-     */
-    synchronized public void setDevice(MtpDevice device) {
-        if (device == mDevice) return;
-        mDevice = device;
-        resetState();
-    }
-
-    /**
-     * Provides a Runnable for the indexing task assuming the state has already
-     * been correctly initialized (by calling {@link #setDevice(MtpDevice)}) and
-     * has not already been run.
-     *
-     * @return Runnable for the main indexing task
-     */
-    synchronized public Runnable getIndexRunnable() {
-        if (mProgress != Progress.Initialized) return null;
-        mProgress = Progress.Pending;
-        return new IndexRunnable(mDevice);
-    }
-
-    synchronized public boolean indexReady() {
-        return mProgress == Progress.Finished;
-    }
-
-    synchronized public Progress getProgress() {
-        return mProgress;
-    }
-
-    /**
-     * @param listener Listener to change to
-     * @return Progress at the time the listener was added (useful for
-     *         configuring initial UI state)
-     */
-    synchronized public Progress setProgressListener(ProgressListener listener) {
-        mProgressListener = listener;
-        return mProgress;
-    }
-
-    /**
-     * Make the listener null if it matches the argument
-     *
-     * @param listener Listener to unset, if currently registered
-     */
-    synchronized public void unsetProgressListener(ProgressListener listener) {
-        if (mProgressListener == listener)
-            mProgressListener = null;
-    }
-
-    /**
-     * @return The total number of elements in the index (labels and items)
-     */
-    public int size() {
-        return mProgress == Progress.Finished ? mUnifiedLookupIndex.length : 0;
-    }
-
-    /**
-     * @param position Index of item to fetch, where 0 is the first item in the
-     *            specified order
-     * @param order
-     * @return the bucket label or MtpObjectInfo at the specified position and
-     *         order
-     */
-    public Object get(int position, SortOrder order) {
-        if (mProgress != Progress.Finished) return null;
-        if(order == SortOrder.Ascending) {
-            DateBucket bucket = mBuckets[mUnifiedLookupIndex[position]];
-            if (bucket.unifiedStartIndex == position) {
-                return bucket.bucket;
-            } else {
-                return mMtpObjects[bucket.itemsStartIndex + position - 1
-                                   - bucket.unifiedStartIndex];
-            }
-        } else {
-            int zeroIndex = mUnifiedLookupIndex.length - 1 - position;
-            DateBucket bucket = mBuckets[mUnifiedLookupIndex[zeroIndex]];
-            if (bucket.unifiedEndIndex == zeroIndex) {
-                return bucket.bucket;
-            } else {
-                return mMtpObjects[bucket.itemsStartIndex + zeroIndex
-                                   - bucket.unifiedStartIndex];
-            }
-        }
-    }
-
-    /**
-     * @param position Index of item to fetch from a view of the data that doesn't
-     *            include labels and is in the specified order
-     * @return position-th item in specified order, when not including labels
-     */
-    public MtpObjectInfo getWithoutLabels(int position, SortOrder order) {
-        if (mProgress != Progress.Finished) return null;
-        if (order == SortOrder.Ascending) {
-            return mMtpObjects[position];
-        } else {
-            return mMtpObjects[mMtpObjects.length - 1 - position];
-        }
-    }
-
-    /**
-     * Although this is O(log(number of buckets)), and thus should not be used
-     * in hotspots, even if the attached device has items for every day for
-     * a five-year timeframe, it would still only take 11 iterations at most,
-     * so shouldn't be a huge issue.
-     * @param position Index of item to map from a view of the data that doesn't
-     *            include labels and is in the specified order
-     * @param order
-     * @return position in a view of the data that does include labels
-     */
-    public int getPositionFromPositionWithoutLabels(int position, SortOrder order) {
-        if (mProgress != Progress.Finished) return -1;
-        if (order == SortOrder.Descending) {
-            position = mMtpObjects.length - 1 - position;
-        }
-        int bucketNumber = 0;
-        int iMin = 0;
-        int iMax = mBuckets.length - 1;
-        while (iMax >= iMin) {
-            int iMid = (iMax + iMin) / 2;
-            if (mBuckets[iMid].itemsStartIndex + mBuckets[iMid].numItems <= position) {
-                iMin = iMid + 1;
-            } else if (mBuckets[iMid].itemsStartIndex > position) {
-                iMax = iMid - 1;
-            } else {
-                bucketNumber = iMid;
-                break;
-            }
-        }
-        if (mBuckets.length == 0 || mUnifiedLookupIndex.length == 0) {
-            return -1;
-        }
-        int mappedPos = mBuckets[bucketNumber].unifiedStartIndex
-                + position - mBuckets[bucketNumber].itemsStartIndex;
-        if (order == SortOrder.Descending) {
-            mappedPos = mUnifiedLookupIndex.length - 1 - mappedPos;
-        }
-        return mappedPos;
-    }
-
-    public int getPositionWithoutLabelsFromPosition(int position, SortOrder order) {
-        if (mProgress != Progress.Finished) return -1;
-        if(order == SortOrder.Ascending) {
-            DateBucket bucket = mBuckets[mUnifiedLookupIndex[position]];
-            if (bucket.unifiedStartIndex == position) position++;
-            return bucket.itemsStartIndex + position - 1 - bucket.unifiedStartIndex;
-        } else {
-            int zeroIndex = mUnifiedLookupIndex.length - 1 - position;
-            if (mBuckets.length == 0 || mUnifiedLookupIndex.length == 0) {
-                return -1;
-            }
-            DateBucket bucket = mBuckets[mUnifiedLookupIndex[zeroIndex]];
-            if (bucket.unifiedEndIndex == zeroIndex) zeroIndex--;
-            return mMtpObjects.length - 1 - bucket.itemsStartIndex
-                    - zeroIndex + bucket.unifiedStartIndex;
-        }
-    }
-
-    /**
-     * @return The number of MTP items in the index (without labels)
-     */
-    public int sizeWithoutLabels() {
-        return mProgress == Progress.Finished ? mMtpObjects.length : 0;
-    }
-
-    public int getFirstPositionForBucketNumber(int bucketNumber, SortOrder order) {
-        if (order == SortOrder.Ascending) {
-            return mBuckets[bucketNumber].unifiedStartIndex;
-        } else {
-            return mUnifiedLookupIndex.length - mBuckets[mBuckets.length - 1 - bucketNumber].unifiedEndIndex - 1;
-        }
-    }
-
-    public int getBucketNumberForPosition(int position, SortOrder order) {
-        if (order == SortOrder.Ascending) {
-            return mUnifiedLookupIndex[position];
-        } else {
-            return mBuckets.length - 1 - mUnifiedLookupIndex[mUnifiedLookupIndex.length - 1 - position];
-        }
-    }
-
-    public boolean isFirstInBucket(int position, SortOrder order) {
-        if (order == SortOrder.Ascending) {
-            return mBuckets[mUnifiedLookupIndex[position]].unifiedStartIndex == position;
-        } else {
-            position = mUnifiedLookupIndex.length - 1 - position;
-            return mBuckets[mUnifiedLookupIndex[position]].unifiedEndIndex == position;
-        }
-    }
-
-    private Object[] mCachedReverseBuckets;
-
-    public Object[] getBuckets(SortOrder order) {
-        if (mBuckets == null) return null;
-        if (order == SortOrder.Ascending) {
-            return mBuckets;
-        } else {
-            if (mCachedReverseBuckets == null) {
-                computeReversedBuckets();
-            }
-            return mCachedReverseBuckets;
-        }
-    }
-
-    /*
-     * See the comments for buildLookupIndex for notes on the specific fields of
-     * this class.
-     */
-    private class DateBucket implements Comparable<DateBucket> {
-        SimpleDate bucket;
-        List<MtpObjectInfo> tempElementsList = new ArrayList<MtpObjectInfo>();
-        int unifiedStartIndex;
-        int unifiedEndIndex;
-        int itemsStartIndex;
-        int numItems;
-
-        public DateBucket(SimpleDate bucket) {
-            this.bucket = bucket;
-        }
-
-        public DateBucket(SimpleDate bucket, MtpObjectInfo firstElement) {
-            this(bucket);
-            tempElementsList.add(firstElement);
-        }
-
-        void sortElements(Comparator<MtpObjectInfo> comparator) {
-            Collections.sort(tempElementsList, comparator);
-        }
-
-        @Override
-        public String toString() {
-            return bucket.toString();
-        }
-
-        @Override
-        public int hashCode() {
-            return bucket.hashCode();
-        }
-
-        @Override
-        public boolean equals(Object obj) {
-            if (this == obj) return true;
-            if (obj == null) return false;
-            if (!(obj instanceof DateBucket)) return false;
-            DateBucket other = (DateBucket) obj;
-            if (bucket == null) {
-                if (other.bucket != null) return false;
-            } else if (!bucket.equals(other.bucket)) {
-                return false;
-            }
-            return true;
-        }
-
-        @Override
-        public int compareTo(DateBucket another) {
-            return this.bucket.compareTo(another.bucket);
-        }
-    }
-
-    /**
-     * Comparator to sort MtpObjectInfo objects by date created.
-     */
-    private static class MtpObjectTimestampComparator implements Comparator<MtpObjectInfo> {
-        @Override
-        public int compare(MtpObjectInfo o1, MtpObjectInfo o2) {
-            long diff = o1.getDateCreated() - o2.getDateCreated();
-            if (diff < 0) {
-                return -1;
-            } else if (diff == 0) {
-                return 0;
-            } else {
-                return 1;
-            }
-        }
-    }
-
-    private void resetState() {
-        mGeneration++;
-        mUnifiedLookupIndex = null;
-        mMtpObjects = null;
-        mBuckets = null;
-        mCachedReverseBuckets = null;
-        mProgress = (mDevice == null) ? Progress.Uninitialized : Progress.Initialized;
-    }
-
-
-    private class IndexRunnable implements Runnable {
-        private int[] mUnifiedLookupIndex;
-        private MtpObjectInfo[] mMtpObjects;
-        private DateBucket[] mBuckets;
-        private Map<SimpleDate, DateBucket> mBucketsTemp;
-        private MtpDevice mDevice;
-        private int mNumObjects = 0;
-
-        private class IndexingException extends Exception {};
-
-        public IndexRunnable(MtpDevice device) {
-            mDevice = device;
-        }
-
-        /*
-         * Implementation note: this is the way the index supports a lot of its operations in
-         * constant time and respecting the need to have bucket names always come before items
-         * in that bucket when accessing the list sequentially, both in ascending and descending
-         * orders.
-         *
-         * Let's say the data we have in the index is the following:
-         *  [Bucket A]: [photo 1], [photo 2]
-         *  [Bucket B]: [photo 3]
-         *
-         *  In this case, the lookup index array would be
-         *  [0, 0, 0, 1, 1]
-         *
-         *  Now, whether we access the list in ascending or descending order, we know which bucket
-         *  to look in (0 corresponds to A and 1 to B), and can return the bucket label as the first
-         *  item in a bucket as needed. The individual IndexBUckets have a startIndex and endIndex
-         *  that correspond to indices in this lookup index array, allowing us to calculate the
-         *  offset of the specific item we want from within a specific bucket.
-         */
-        private void buildLookupIndex() {
-            int numBuckets = mBuckets.length;
-            mUnifiedLookupIndex = new int[mNumObjects + numBuckets];
-            int currentUnifiedIndexEntry = 0;
-            int nextUnifiedEntry;
-
-            mMtpObjects = new MtpObjectInfo[mNumObjects];
-            int currentItemsEntry = 0;
-            for (int i = 0; i < numBuckets; i++) {
-                DateBucket bucket = mBuckets[i];
-                nextUnifiedEntry = currentUnifiedIndexEntry + bucket.tempElementsList.size() + 1;
-                Arrays.fill(mUnifiedLookupIndex, currentUnifiedIndexEntry, nextUnifiedEntry, i);
-                bucket.unifiedStartIndex = currentUnifiedIndexEntry;
-                bucket.unifiedEndIndex = nextUnifiedEntry - 1;
-                currentUnifiedIndexEntry = nextUnifiedEntry;
-
-                bucket.itemsStartIndex = currentItemsEntry;
-                bucket.numItems = bucket.tempElementsList.size();
-                for (int j = 0; j < bucket.numItems; j++) {
-                    mMtpObjects[currentItemsEntry] = bucket.tempElementsList.get(j);
-                    currentItemsEntry++;
-                }
-                bucket.tempElementsList = null;
-            }
-        }
-
-        private void copyResults() {
-            MtpDeviceIndex.this.mUnifiedLookupIndex = mUnifiedLookupIndex;
-            MtpDeviceIndex.this.mMtpObjects = mMtpObjects;
-            MtpDeviceIndex.this.mBuckets = mBuckets;
-            mUnifiedLookupIndex = null;
-            mMtpObjects = null;
-            mBuckets = null;
-        }
-
-        @Override
-        public void run() {
-            try {
-                indexDevice();
-            } catch (IndexingException e) {
-                synchronized (MtpDeviceIndex.this) {
-                    resetState();
-                    if (mProgressListener != null) {
-                        mProgressListener.onIndexFinish();
-                    }
-                }
-            }
-        }
-
-        private void indexDevice() throws IndexingException {
-            synchronized (MtpDeviceIndex.this) {
-                mProgress = Progress.Started;
-            }
-            mBucketsTemp = new HashMap<SimpleDate, DateBucket>();
-            for (int storageId : mDevice.getStorageIds()) {
-                if (mDevice != getDevice()) throw new IndexingException();
-                Stack<Integer> pendingDirectories = new Stack<Integer>();
-                pendingDirectories.add(0xFFFFFFFF); // start at the root of the device
-                while (!pendingDirectories.isEmpty()) {
-                    if (mDevice != getDevice()) throw new IndexingException();
-                    int dirHandle = pendingDirectories.pop();
-                    for (int objectHandle : mDevice.getObjectHandles(storageId, 0, dirHandle)) {
-                        MtpObjectInfo objectInfo = mDevice.getObjectInfo(objectHandle);
-                        if (objectInfo == null) throw new IndexingException();
-                        int format = objectInfo.getFormat();
-                        if (format == MtpConstants.FORMAT_ASSOCIATION) {
-                            pendingDirectories.add(objectHandle);
-                        } else if (SUPPORTED_IMAGE_FORMATS.contains(format)
-                                || SUPPORTED_VIDEO_FORMATS.contains(format)) {
-                            addObject(objectInfo);
-                        }
-                    }
-                }
-            }
-            Collection<DateBucket> values = mBucketsTemp.values();
-            mBucketsTemp = null;
-            mBuckets = values.toArray(new DateBucket[values.size()]);
-            values = null;
-            synchronized (MtpDeviceIndex.this) {
-                mProgress = Progress.Sorting;
-                if (mProgressListener != null) {
-                    mProgressListener.onSorting();
-                }
-            }
-            sortAll();
-            buildLookupIndex();
-            synchronized (MtpDeviceIndex.this) {
-                if (mDevice != getDevice()) throw new IndexingException();
-                copyResults();
-
-                /*
-                 * In order for getBuckets to operate in constant time for descending
-                 * order, we must precompute a reversed array of the buckets, mainly
-                 * because the android.widget.SectionIndexer interface which adapters
-                 * that call getBuckets implement depends on section numbers to be
-                 * ascending relative to the scroll position, so we must have this for
-                 * descending order or the scrollbar goes crazy.
-                 */
-                computeReversedBuckets();
-
-                mProgress = Progress.Finished;
-                if (mProgressListener != null) {
-                    mProgressListener.onIndexFinish();
-                }
-            }
-        }
-
-        private SimpleDate mDateInstance = new SimpleDate();
-
-        private void addObject(MtpObjectInfo objectInfo) {
-            mNumObjects++;
-            mDateInstance.setTimestamp(objectInfo.getDateCreated());
-            DateBucket bucket = mBucketsTemp.get(mDateInstance);
-            if (bucket == null) {
-                bucket = new DateBucket(mDateInstance, objectInfo);
-                mBucketsTemp.put(mDateInstance, bucket);
-                mDateInstance = new SimpleDate(); // only create new date
-                                                  // objects when they are used
-                return;
-            } else {
-                bucket.tempElementsList.add(objectInfo);
-            }
-            if (mProgressListener != null) {
-                mProgressListener.onObjectIndexed(objectInfo, mNumObjects);
-            }
-        }
-
-        private void sortAll() {
-            Arrays.sort(mBuckets);
-            for (DateBucket bucket : mBuckets) {
-                bucket.sortElements(sMtpObjectComparator);
-            }
-        }
-
-    }
-
-    private void computeReversedBuckets() {
-        mCachedReverseBuckets = new Object[mBuckets.length];
-        for (int i = 0; i < mCachedReverseBuckets.length; i++) {
-            mCachedReverseBuckets[i] = mBuckets[mBuckets.length - 1 - i];
-        }
-    }
-}
diff --git a/src/com/android/gallery3d/ingest/SimpleDate.java b/src/com/android/gallery3d/ingest/SimpleDate.java
deleted file mode 100644
index 05db2cd..0000000
--- a/src/com/android/gallery3d/ingest/SimpleDate.java
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.gallery3d.ingest;
-
-import java.text.DateFormat;
-import java.util.Calendar;
-
-/**
- * Represents a date (year, month, day)
- */
-public class SimpleDate implements Comparable<SimpleDate> {
-    public int month; // MM
-    public int day; // DD
-    public int year; // YYYY
-    private long timestamp;
-    private String mCachedStringRepresentation;
-
-    public SimpleDate() {
-    }
-
-    public SimpleDate(long timestamp) {
-        setTimestamp(timestamp);
-    }
-
-    private static Calendar sCalendarInstance = Calendar.getInstance();
-
-    public void setTimestamp(long timestamp) {
-        synchronized (sCalendarInstance) {
-            // TODO find a more efficient way to convert a timestamp to a date?
-            sCalendarInstance.setTimeInMillis(timestamp);
-            this.day = sCalendarInstance.get(Calendar.DATE);
-            this.month = sCalendarInstance.get(Calendar.MONTH);
-            this.year = sCalendarInstance.get(Calendar.YEAR);
-            this.timestamp = timestamp;
-            mCachedStringRepresentation = DateFormat.getDateInstance(DateFormat.SHORT).format(timestamp);
-        }
-    }
-
-    @Override
-    public int hashCode() {
-        final int prime = 31;
-        int result = 1;
-        result = prime * result + day;
-        result = prime * result + month;
-        result = prime * result + year;
-        return result;
-    }
-
-    @Override
-    public boolean equals(Object obj) {
-        if (this == obj)
-            return true;
-        if (obj == null)
-            return false;
-        if (!(obj instanceof SimpleDate))
-            return false;
-        SimpleDate other = (SimpleDate) obj;
-        if (year != other.year)
-            return false;
-        if (month != other.month)
-            return false;
-        if (day != other.day)
-            return false;
-        return true;
-    }
-
-    @Override
-    public int compareTo(SimpleDate other) {
-        int yearDiff = this.year - other.getYear();
-        if (yearDiff != 0)
-            return yearDiff;
-        else {
-            int monthDiff = this.month - other.getMonth();
-            if (monthDiff != 0)
-                return monthDiff;
-            else
-                return this.day - other.getDay();
-        }
-    }
-
-    public int getDay() {
-        return day;
-    }
-
-    public int getMonth() {
-        return month;
-    }
-
-    public int getYear() {
-        return year;
-    }
-
-    @Override
-    public String toString() {
-        if (mCachedStringRepresentation == null) {
-            mCachedStringRepresentation = DateFormat.getDateInstance(DateFormat.SHORT).format(timestamp);
-        }
-        return mCachedStringRepresentation;
-    }
-}
diff --git a/src/com/android/gallery3d/ingest/adapter/CheckBroker.java b/src/com/android/gallery3d/ingest/adapter/CheckBroker.java
index 6783f23..dc8723f 100644
--- a/src/com/android/gallery3d/ingest/adapter/CheckBroker.java
+++ b/src/com/android/gallery3d/ingest/adapter/CheckBroker.java
@@ -16,41 +16,52 @@
 
 package com.android.gallery3d.ingest.adapter;
 
+import android.annotation.TargetApi;
+import android.os.Build;
+
 import java.util.ArrayList;
 import java.util.Collection;
 
+/**
+ * Helper to keep checked state in sync.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public abstract class CheckBroker {
-    private Collection<OnCheckedChangedListener> mListeners =
-            new ArrayList<OnCheckedChangedListener>();
+  private Collection<OnCheckedChangedListener> mListeners =
+      new ArrayList<OnCheckedChangedListener>();
 
-    public interface OnCheckedChangedListener {
-        public void onCheckedChanged(int position, boolean isChecked);
-        public void onBulkCheckedChanged();
+  /**
+   * Listener for item checked state changes.
+   */
+  public interface OnCheckedChangedListener {
+    public void onCheckedChanged(int position, boolean isChecked);
+
+    public void onBulkCheckedChanged();
+  }
+
+  public abstract void setItemChecked(int position, boolean checked);
+
+  public void onCheckedChange(int position, boolean checked) {
+    if (isItemChecked(position) != checked) {
+      for (OnCheckedChangedListener l : mListeners) {
+        l.onCheckedChanged(position, checked);
+      }
     }
+  }
 
-    public abstract void setItemChecked(int position, boolean checked);
-
-    public void onCheckedChange(int position, boolean checked) {
-        if (isItemChecked(position) != checked) {
-            for (OnCheckedChangedListener l : mListeners) {
-                l.onCheckedChanged(position, checked);
-            }
-        }
+  public void onBulkCheckedChange() {
+    for (OnCheckedChangedListener l : mListeners) {
+      l.onBulkCheckedChanged();
     }
+  }
 
-    public void onBulkCheckedChange() {
-        for (OnCheckedChangedListener l : mListeners) {
-            l.onBulkCheckedChanged();
-        }
-    }
+  public abstract boolean isItemChecked(int position);
 
-    public abstract boolean isItemChecked(int position);
+  public void registerOnCheckedChangeListener(OnCheckedChangedListener l) {
+    mListeners.add(l);
+  }
 
-    public void registerOnCheckedChangeListener(OnCheckedChangedListener l) {
-        mListeners.add(l);
-    }
-
-    public void unregisterOnCheckedChangeListener(OnCheckedChangedListener l) {
-        mListeners.remove(l);
-    }
+  public void unregisterOnCheckedChangeListener(OnCheckedChangedListener l) {
+    mListeners.remove(l);
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java b/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
index e8dd69f..c3ce59f 100644
--- a/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
+++ b/src/com/android/gallery3d/ingest/adapter/MtpAdapter.java
@@ -16,177 +16,187 @@
 
 package com.android.gallery3d.ingest.adapter;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex.SortOrder;
+import com.android.gallery3d.ingest.data.SimpleDate;
+import com.android.gallery3d.ingest.ui.DateTileView;
+import com.android.gallery3d.ingest.ui.MtpThumbnailTileView;
+
+import android.annotation.TargetApi;
 import android.app.Activity;
 import android.content.Context;
-import android.mtp.MtpObjectInfo;
+import android.os.Build;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.BaseAdapter;
 import android.widget.SectionIndexer;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.MtpDeviceIndex;
-import com.android.gallery3d.ingest.MtpDeviceIndex.SortOrder;
-import com.android.gallery3d.ingest.SimpleDate;
-import com.android.gallery3d.ingest.ui.DateTileView;
-import com.android.gallery3d.ingest.ui.MtpThumbnailTileView;
-
+/**
+ * Adapter for MTP thumbnail grid.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class MtpAdapter extends BaseAdapter implements SectionIndexer {
-    public static final int ITEM_TYPE_MEDIA = 0;
-    public static final int ITEM_TYPE_BUCKET = 1;
+  public static final int ITEM_TYPE_MEDIA = 0;
+  public static final int ITEM_TYPE_BUCKET = 1;
 
-    private Context mContext;
-    private MtpDeviceIndex mModel;
-    private SortOrder mSortOrder = SortOrder.Descending;
-    private LayoutInflater mInflater;
-    private int mGeneration = 0;
+  @SuppressWarnings("unused")
+  private Context mContext;
+  private MtpDeviceIndex mModel;
+  private SortOrder mSortOrder = SortOrder.DESCENDING;
+  private LayoutInflater mInflater;
+  private int mGeneration = 0;
 
-    public MtpAdapter(Activity context) {
-        super();
-        mContext = context;
-        mInflater = LayoutInflater.from(context);
+  public MtpAdapter(Activity context) {
+    super();
+    mContext = context;
+    mInflater = LayoutInflater.from(context);
+  }
+
+  public void setMtpDeviceIndex(MtpDeviceIndex index) {
+    mModel = index;
+    notifyDataSetChanged();
+  }
+
+  public MtpDeviceIndex getMtpDeviceIndex() {
+    return mModel;
+  }
+
+  @Override
+  public void notifyDataSetChanged() {
+    mGeneration++;
+    super.notifyDataSetChanged();
+  }
+
+  @Override
+  public void notifyDataSetInvalidated() {
+    mGeneration++;
+    super.notifyDataSetInvalidated();
+  }
+
+  public boolean deviceConnected() {
+    return (mModel != null) && mModel.isDeviceConnected();
+  }
+
+  public boolean indexReady() {
+    return (mModel != null) && mModel.isIndexReady();
+  }
+
+  @Override
+  public int getCount() {
+    return mModel != null ? mModel.size() : 0;
+  }
+
+  @Override
+  public Object getItem(int position) {
+    return mModel.get(position, mSortOrder);
+  }
+
+  @Override
+  public boolean areAllItemsEnabled() {
+    return true;
+  }
+
+  @Override
+  public boolean isEnabled(int position) {
+    return true;
+  }
+
+  @Override
+  public long getItemId(int position) {
+    return position;
+  }
+
+  @Override
+  public int getViewTypeCount() {
+    return 2;
+  }
+
+  @Override
+  public int getItemViewType(int position) {
+    // If the position is the first in its section, then it corresponds to
+    // a title tile, if not it's a media tile
+    if (position == getPositionForSection(getSectionForPosition(position))) {
+      return ITEM_TYPE_BUCKET;
+    } else {
+      return ITEM_TYPE_MEDIA;
     }
+  }
 
-    public void setMtpDeviceIndex(MtpDeviceIndex index) {
-        mModel = index;
-        notifyDataSetChanged();
-    }
+  public boolean itemAtPositionIsBucket(int position) {
+    return getItemViewType(position) == ITEM_TYPE_BUCKET;
+  }
 
-    public MtpDeviceIndex getMtpDeviceIndex() {
-        return mModel;
-    }
+  public boolean itemAtPositionIsMedia(int position) {
+    return getItemViewType(position) == ITEM_TYPE_MEDIA;
+  }
 
-    @Override
-    public void notifyDataSetChanged() {
-        mGeneration++;
-        super.notifyDataSetChanged();
+  @Override
+  public View getView(int position, View convertView, ViewGroup parent) {
+    int type = getItemViewType(position);
+    if (type == ITEM_TYPE_MEDIA) {
+      MtpThumbnailTileView imageView;
+      if (convertView == null) {
+        imageView = (MtpThumbnailTileView) mInflater.inflate(
+            R.layout.ingest_thumbnail, parent, false);
+      } else {
+        imageView = (MtpThumbnailTileView) convertView;
+      }
+      imageView.setMtpDeviceAndObjectInfo(mModel.getDevice(),
+          (IngestObjectInfo) getItem(position), mGeneration);
+      return imageView;
+    } else {
+      DateTileView dateTile;
+      if (convertView == null) {
+        dateTile = (DateTileView) mInflater.inflate(
+            R.layout.ingest_date_tile, parent, false);
+      } else {
+        dateTile = (DateTileView) convertView;
+      }
+      dateTile.setDate((SimpleDate) getItem(position));
+      return dateTile;
     }
+  }
 
-    @Override
-    public void notifyDataSetInvalidated() {
-        mGeneration++;
-        super.notifyDataSetInvalidated();
+  @Override
+  public int getPositionForSection(int section) {
+    if (getCount() == 0) {
+      return 0;
     }
+    int numSections = getSections().length;
+    if (section >= numSections) {
+      section = numSections - 1;
+    }
+    return mModel.getFirstPositionForBucketNumber(section, mSortOrder);
+  }
 
-    public boolean deviceConnected() {
-        return (mModel != null) && (mModel.getDevice() != null);
+  @Override
+  public int getSectionForPosition(int position) {
+    int count = getCount();
+    if (count == 0) {
+      return 0;
     }
+    if (position >= count) {
+      position = count - 1;
+    }
+    return mModel.getBucketNumberForPosition(position, mSortOrder);
+  }
 
-    public boolean indexReady() {
-        return (mModel != null) && mModel.indexReady();
-    }
+  @Override
+  public Object[] getSections() {
+    return getCount() > 0 ? mModel.getBuckets(mSortOrder) : null;
+  }
 
-    @Override
-    public int getCount() {
-        return mModel != null ? mModel.size() : 0;
-    }
+  public SortOrder getSortOrder() {
+    return mSortOrder;
+  }
 
-    @Override
-    public Object getItem(int position) {
-        return mModel.get(position, mSortOrder);
+  public int translatePositionWithoutLabels(int position) {
+    if (mModel == null) {
+      return -1;
     }
-
-    @Override
-    public boolean areAllItemsEnabled() {
-        return true;
-    }
-
-    @Override
-    public boolean isEnabled(int position) {
-        return true;
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public int getViewTypeCount() {
-        return 2;
-    }
-
-    @Override
-    public int getItemViewType(int position) {
-        // If the position is the first in its section, then it corresponds to
-        // a title tile, if not it's a media tile
-        if (position == getPositionForSection(getSectionForPosition(position))) {
-            return ITEM_TYPE_BUCKET;
-        } else {
-            return ITEM_TYPE_MEDIA;
-        }
-    }
-
-    public boolean itemAtPositionIsBucket(int position) {
-        return getItemViewType(position) == ITEM_TYPE_BUCKET;
-    }
-
-    public boolean itemAtPositionIsMedia(int position) {
-        return getItemViewType(position) == ITEM_TYPE_MEDIA;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        int type = getItemViewType(position);
-        if (type == ITEM_TYPE_MEDIA) {
-            MtpThumbnailTileView imageView;
-            if (convertView == null) {
-                imageView = (MtpThumbnailTileView) mInflater.inflate(
-                        R.layout.ingest_thumbnail, parent, false);
-            } else {
-                imageView = (MtpThumbnailTileView) convertView;
-            }
-            imageView.setMtpDeviceAndObjectInfo(mModel.getDevice(), (MtpObjectInfo)getItem(position), mGeneration);
-            return imageView;
-        } else {
-            DateTileView dateTile;
-            if (convertView == null) {
-                dateTile = (DateTileView) mInflater.inflate(
-                        R.layout.ingest_date_tile, parent, false);
-            } else {
-                dateTile = (DateTileView) convertView;
-            }
-            dateTile.setDate((SimpleDate)getItem(position));
-            return dateTile;
-        }
-    }
-
-    @Override
-    public int getPositionForSection(int section) {
-        if (getCount() == 0) {
-            return 0;
-        }
-        int numSections = getSections().length;
-        if (section >= numSections) {
-            section = numSections - 1;
-        }
-        return mModel.getFirstPositionForBucketNumber(section, mSortOrder);
-    }
-
-    @Override
-    public int getSectionForPosition(int position) {
-        int count = getCount();
-        if (count == 0) {
-            return 0;
-        }
-        if (position >= count) {
-            position = count - 1;
-        }
-        return mModel.getBucketNumberForPosition(position, mSortOrder);
-    }
-
-    @Override
-    public Object[] getSections() {
-        return getCount() > 0 ? mModel.getBuckets(mSortOrder) : null;
-    }
-
-    public SortOrder getSortOrder() {
-        return mSortOrder;
-    }
-
-    public int translatePositionWithoutLabels(int position) {
-        if (mModel == null) return -1;
-        return mModel.getPositionFromPositionWithoutLabels(position, mSortOrder);
-    }
+    return mModel.getPositionFromPositionWithoutLabels(position, mSortOrder);
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java b/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java
index 9e7abc0..9fe650c 100644
--- a/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java
+++ b/src/com/android/gallery3d/ingest/adapter/MtpPagerAdapter.java
@@ -16,87 +16,95 @@
 
 package com.android.gallery3d.ingest.adapter;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex.SortOrder;
+import com.android.gallery3d.ingest.ui.MtpFullscreenView;
+
+import android.annotation.TargetApi;
 import android.content.Context;
-import android.mtp.MtpObjectInfo;
+import android.os.Build;
 import android.support.v4.view.PagerAdapter;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.MtpDeviceIndex;
-import com.android.gallery3d.ingest.MtpDeviceIndex.SortOrder;
-import com.android.gallery3d.ingest.ui.MtpFullscreenView;
-
+/**
+ * Adapter for full-screen MTP pager.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class MtpPagerAdapter extends PagerAdapter {
 
-    private LayoutInflater mInflater;
-    private int mGeneration = 0;
-    private CheckBroker mBroker;
-    private MtpDeviceIndex mModel;
-    private SortOrder mSortOrder = SortOrder.Descending;
+  private LayoutInflater mInflater;
+  private int mGeneration = 0;
+  private CheckBroker mBroker;
+  private MtpDeviceIndex mModel;
+  private SortOrder mSortOrder = SortOrder.DESCENDING;
 
-    private MtpFullscreenView mReusableView = null;
+  private MtpFullscreenView mReusableView = null;
 
-    public MtpPagerAdapter(Context context, CheckBroker broker) {
-        super();
-        mInflater = LayoutInflater.from(context);
-        mBroker = broker;
+  public MtpPagerAdapter(Context context, CheckBroker broker) {
+    super();
+    mInflater = LayoutInflater.from(context);
+    mBroker = broker;
+  }
+
+  public void setMtpDeviceIndex(MtpDeviceIndex index) {
+    mModel = index;
+    notifyDataSetChanged();
+  }
+
+  @Override
+  public int getCount() {
+    return mModel != null ? mModel.sizeWithoutLabels() : 0;
+  }
+
+  @Override
+  public void notifyDataSetChanged() {
+    mGeneration++;
+    super.notifyDataSetChanged();
+  }
+
+  public int translatePositionWithLabels(int position) {
+    if (mModel == null) {
+      return -1;
     }
+    return mModel.getPositionWithoutLabelsFromPosition(position, mSortOrder);
+  }
 
-    public void setMtpDeviceIndex(MtpDeviceIndex index) {
-        mModel = index;
-        notifyDataSetChanged();
-    }
+  @Override
+  public void finishUpdate(ViewGroup container) {
+    mReusableView = null;
+    super.finishUpdate(container);
+  }
 
-    @Override
-    public int getCount() {
-        return mModel != null ? mModel.sizeWithoutLabels() : 0;
-    }
+  @Override
+  public boolean isViewFromObject(View view, Object object) {
+    return view == object;
+  }
 
-    @Override
-    public void notifyDataSetChanged() {
-        mGeneration++;
-        super.notifyDataSetChanged();
-    }
+  @Override
+  public void destroyItem(ViewGroup container, int position, Object object) {
+    MtpFullscreenView v = (MtpFullscreenView) object;
+    container.removeView(v);
+    mBroker.unregisterOnCheckedChangeListener(v);
+    mReusableView = v;
+  }
 
-    public int translatePositionWithLabels(int position) {
-        if (mModel == null) return -1;
-        return mModel.getPositionWithoutLabelsFromPosition(position, mSortOrder);
+  @Override
+  public Object instantiateItem(ViewGroup container, int position) {
+    MtpFullscreenView v;
+    if (mReusableView != null) {
+      v = mReusableView;
+      mReusableView = null;
+    } else {
+      v = (MtpFullscreenView) mInflater.inflate(R.layout.ingest_fullsize, container, false);
     }
-
-    @Override
-    public void finishUpdate(ViewGroup container) {
-        mReusableView = null;
-        super.finishUpdate(container);
-    }
-
-    @Override
-    public boolean isViewFromObject(View view, Object object) {
-        return view == object;
-    }
-
-    @Override
-    public void destroyItem(ViewGroup container, int position, Object object) {
-        MtpFullscreenView v = (MtpFullscreenView)object;
-        container.removeView(v);
-        mBroker.unregisterOnCheckedChangeListener(v);
-        mReusableView = v;
-    }
-
-    @Override
-    public Object instantiateItem(ViewGroup container, int position) {
-        MtpFullscreenView v;
-        if (mReusableView != null) {
-            v = mReusableView;
-            mReusableView = null;
-        } else {
-            v = (MtpFullscreenView) mInflater.inflate(R.layout.ingest_fullsize, container, false);
-        }
-        MtpObjectInfo i = mModel.getWithoutLabels(position, mSortOrder);
-        v.getImageView().setMtpDeviceAndObjectInfo(mModel.getDevice(), i, mGeneration);
-        v.setPositionAndBroker(position, mBroker);
-        container.addView(v);
-        return v;
-    }
+    IngestObjectInfo i = mModel.getWithoutLabels(position, mSortOrder);
+    v.getImageView().setMtpDeviceAndObjectInfo(mModel.getDevice(), i, mGeneration);
+    v.setPositionAndBroker(position, mBroker);
+    container.addView(v);
+    return v;
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java b/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java
index bbc90f6..c436fa7 100644
--- a/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java
+++ b/src/com/android/gallery3d/ingest/data/BitmapWithMetadata.java
@@ -16,14 +16,20 @@
 
 package com.android.gallery3d.ingest.data;
 
+import android.annotation.TargetApi;
 import android.graphics.Bitmap;
+import android.os.Build;
 
+/**
+ * Encapsulates a Bitmap and some additional metadata.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class BitmapWithMetadata {
-    public Bitmap bitmap;
-    public int rotationDegrees;
+  public Bitmap bitmap;
+  public int rotationDegrees;
 
-    public BitmapWithMetadata(Bitmap bitmap, int rotationDegrees) {
-        this.bitmap = bitmap;
-        this.rotationDegrees = rotationDegrees;
-    }
+  public BitmapWithMetadata(Bitmap bitmap, int rotationDegrees) {
+    this.bitmap = bitmap;
+    this.rotationDegrees = rotationDegrees;
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/data/DateBucket.java b/src/com/android/gallery3d/ingest/data/DateBucket.java
new file mode 100644
index 0000000..85eedb3
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/DateBucket.java
@@ -0,0 +1,63 @@
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+/**
+ * Date bucket for {@link MtpDeviceIndex}.
+ * See {@link MtpDeviceIndexRunnable} for implementation notes.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+class DateBucket implements Comparable<DateBucket> {
+  final SimpleDate date;
+  final int unifiedStartIndex;
+  final int unifiedEndIndex;
+  final int itemsStartIndex;
+  final int numItems;
+
+  public DateBucket(SimpleDate date, int unifiedStartIndex, int unifiedEndIndex,
+      int itemsStartIndex, int numItems) {
+    this.date = date;
+    this.unifiedStartIndex = unifiedStartIndex;
+    this.unifiedEndIndex = unifiedEndIndex;
+    this.itemsStartIndex = itemsStartIndex;
+    this.numItems = numItems;
+  }
+
+  @Override
+  public String toString() {
+    return date.toString();
+  }
+
+  @Override
+  public int hashCode() {
+    return date.hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (!(obj instanceof DateBucket)) {
+      return false;
+    }
+    DateBucket other = (DateBucket) obj;
+    if (date == null) {
+      if (other.date != null) {
+        return false;
+      }
+    } else if (!date.equals(other.date)) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public int compareTo(DateBucket another) {
+    return this.date.compareTo(another.date);
+  }
+}
\ No newline at end of file
diff --git a/src/com/android/gallery3d/ingest/data/ImportTask.java b/src/com/android/gallery3d/ingest/data/ImportTask.java
new file mode 100644
index 0000000..ee2a7d0
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/ImportTask.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.content.Context;
+import android.mtp.MtpDevice;
+import android.os.Build;
+import android.os.Environment;
+import android.os.PowerManager;
+import android.os.StatFs;
+import android.util.Log;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.LinkedList;
+import java.util.List;
+
+/**
+ * Task that handles the copying of items from an MTP device.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class ImportTask implements Runnable {
+
+  private static final String TAG = "ImportTask";
+
+  /**
+   * Import progress listener.
+   */
+  public interface Listener {
+    void onImportProgress(int visitedCount, int totalCount, String pathIfSuccessful);
+
+    void onImportFinish(Collection<IngestObjectInfo> objectsNotImported, int visitedCount);
+  }
+
+  private static final String WAKELOCK_LABEL = "Google Photos MTP Import Task";
+
+  private Listener mListener;
+  private String mDestAlbumName;
+  private Collection<IngestObjectInfo> mObjectsToImport;
+  private MtpDevice mDevice;
+  private PowerManager.WakeLock mWakeLock;
+
+  public ImportTask(MtpDevice device, Collection<IngestObjectInfo> objectsToImport,
+      String destAlbumName, Context context) {
+    mDestAlbumName = destAlbumName;
+    mObjectsToImport = objectsToImport;
+    mDevice = device;
+    PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+    mWakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, WAKELOCK_LABEL);
+  }
+
+  public void setListener(Listener listener) {
+    mListener = listener;
+  }
+
+  @Override
+  public void run() {
+    mWakeLock.acquire();
+    try {
+      List<IngestObjectInfo> objectsNotImported = new LinkedList<IngestObjectInfo>();
+      int visited = 0;
+      int total = mObjectsToImport.size();
+      mListener.onImportProgress(visited, total, null);
+      File dest = new File(Environment.getExternalStorageDirectory(), mDestAlbumName);
+      dest.mkdirs();
+      for (IngestObjectInfo object : mObjectsToImport) {
+        visited++;
+        String importedPath = null;
+        if (hasSpaceForSize(object.getCompressedSize())) {
+          importedPath = new File(dest, object.getName(mDevice)).getAbsolutePath();
+          if (!mDevice.importFile(object.getObjectHandle(), importedPath)) {
+            importedPath = null;
+          }
+        }
+        if (importedPath == null) {
+          objectsNotImported.add(object);
+        }
+        if (mListener != null) {
+          mListener.onImportProgress(visited, total, importedPath);
+        }
+      }
+      if (mListener != null) {
+        mListener.onImportFinish(objectsNotImported, visited);
+      }
+    } finally {
+      mListener = null;
+      mWakeLock.release();
+    }
+  }
+
+  private static boolean hasSpaceForSize(long size) {
+    String state = Environment.getExternalStorageState();
+    if (!Environment.MEDIA_MOUNTED.equals(state)) {
+      return false;
+    }
+
+    String path = Environment.getExternalStorageDirectory().getPath();
+    try {
+      StatFs stat = new StatFs(path);
+      return stat.getAvailableBlocks() * (long) stat.getBlockSize() > size;
+    } catch (Exception e) {
+      Log.i(TAG, "Fail to access external storage", e);
+    }
+    return false;
+  }
+}
diff --git a/src/com/android/gallery3d/ingest/data/IngestObjectInfo.java b/src/com/android/gallery3d/ingest/data/IngestObjectInfo.java
new file mode 100644
index 0000000..2527383
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/IngestObjectInfo.java
@@ -0,0 +1,114 @@
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
+import android.os.Build;
+
+/**
+ * Holds the info needed for the in-memory index of MTP objects.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class IngestObjectInfo implements Comparable<IngestObjectInfo> {
+
+  private int mHandle;
+  private long mDateCreated;
+  private int mFormat;
+  private int mCompressedSize;
+
+  public IngestObjectInfo(MtpObjectInfo mtpObjectInfo) {
+    mHandle = mtpObjectInfo.getObjectHandle();
+    mDateCreated = mtpObjectInfo.getDateCreated();
+    mFormat = mtpObjectInfo.getFormat();
+    mCompressedSize = mtpObjectInfo.getCompressedSize();
+  }
+
+  public IngestObjectInfo(int handle, long dateCreated, int format, int compressedSize) {
+    mHandle = handle;
+    mDateCreated = dateCreated;
+    mFormat = format;
+    mCompressedSize = compressedSize;
+  }
+
+  public int getCompressedSize() {
+    return mCompressedSize;
+  }
+
+  public int getFormat() {
+    return mFormat;
+  }
+
+  public long getDateCreated() {
+    return mDateCreated;
+  }
+
+  public int getObjectHandle() {
+    return mHandle;
+  }
+
+  public String getName(MtpDevice device) {
+    if (device != null) {
+      MtpObjectInfo info = device.getObjectInfo(mHandle);
+      if (info != null) {
+        return info.getName();
+      }
+    }
+    return null;
+  }
+
+  @Override
+  public int compareTo(IngestObjectInfo another) {
+    long diff = getDateCreated() - another.getDateCreated();
+    if (diff < 0) {
+      return -1;
+    } else if (diff == 0) {
+      return 0;
+    } else {
+      return 1;
+    }
+  }
+
+  @Override
+  public String toString() {
+    return "IngestObjectInfo [mHandle=" + mHandle + ", mDateCreated=" + mDateCreated
+        + ", mFormat=" + mFormat + ", mCompressedSize=" + mCompressedSize + "]";
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + mCompressedSize;
+    result = prime * result + (int) (mDateCreated ^ (mDateCreated >>> 32));
+    result = prime * result + mFormat;
+    result = prime * result + mHandle;
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (!(obj instanceof IngestObjectInfo)) {
+      return false;
+    }
+    IngestObjectInfo other = (IngestObjectInfo) obj;
+    if (mCompressedSize != other.mCompressedSize) {
+      return false;
+    }
+    if (mDateCreated != other.mDateCreated) {
+      return false;
+    }
+    if (mFormat != other.mFormat) {
+      return false;
+    }
+    if (mHandle != other.mHandle) {
+      return false;
+    }
+    return true;
+  }
+}
diff --git a/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
index c6504a5..3295828 100644
--- a/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
+++ b/src/com/android/gallery3d/ingest/data/MtpBitmapFetch.java
@@ -16,91 +16,98 @@
 
 package com.android.gallery3d.ingest.data;
 
+import android.annotation.TargetApi;
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.mtp.MtpDevice;
-import android.mtp.MtpObjectInfo;
+import android.os.Build;
 import android.util.DisplayMetrics;
 import android.view.WindowManager;
 
 import com.android.gallery3d.data.Exif;
 import com.android.photos.data.GalleryBitmapPool;
 
+/**
+ * Helper class for fetching bitmaps from MTP devices.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
 public class MtpBitmapFetch {
-    private static int sMaxSize = 0;
+  private static int sMaxSize = 0;
 
-    public static void recycleThumbnail(Bitmap b) {
-        if (b != null) {
-            GalleryBitmapPool.getInstance().put(b);
-        }
+  public static void recycleThumbnail(Bitmap b) {
+    if (b != null) {
+      GalleryBitmapPool.getInstance().put(b);
+    }
+  }
+
+  public static Bitmap getThumbnail(MtpDevice device, IngestObjectInfo info) {
+    byte[] imageBytes = device.getThumbnail(info.getObjectHandle());
+    if (imageBytes == null) {
+      return null;
+    }
+    BitmapFactory.Options o = new BitmapFactory.Options();
+    o.inJustDecodeBounds = true;
+    BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+    if (o.outWidth == 0 || o.outHeight == 0) {
+      return null;
+    }
+    o.inBitmap = GalleryBitmapPool.getInstance().get(o.outWidth, o.outHeight);
+    o.inMutable = true;
+    o.inJustDecodeBounds = false;
+    o.inSampleSize = 1;
+    try {
+      return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+    } catch (IllegalArgumentException e) {
+      // BitmapFactory throws an exception rather than returning null
+      // when image decoding fails and an existing bitmap was supplied
+      // for recycling, even if the failure was not caused by the use
+      // of that bitmap.
+      return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
+    }
+  }
+
+  public static BitmapWithMetadata getFullsize(MtpDevice device, IngestObjectInfo info) {
+    return getFullsize(device, info, sMaxSize);
+  }
+
+  public static BitmapWithMetadata getFullsize(MtpDevice device, IngestObjectInfo info,
+      int maxSide) {
+    byte[] imageBytes = device.getObject(info.getObjectHandle(), info.getCompressedSize());
+    if (imageBytes == null) {
+      return null;
+    }
+    Bitmap created;
+    if (maxSide > 0) {
+      BitmapFactory.Options o = new BitmapFactory.Options();
+      o.inJustDecodeBounds = true;
+      BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+      int w = o.outWidth;
+      int h = o.outHeight;
+      int comp = Math.max(h, w);
+      int sampleSize = 1;
+      while ((comp >> 1) >= maxSide) {
+        comp = comp >> 1;
+        sampleSize++;
+      }
+      o.inSampleSize = sampleSize;
+      o.inJustDecodeBounds = false;
+      created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
+    } else {
+      created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
+    }
+    if (created == null) {
+      return null;
     }
 
-    public static Bitmap getThumbnail(MtpDevice device, MtpObjectInfo info) {
-        byte[] imageBytes = device.getThumbnail(info.getObjectHandle());
-        if (imageBytes == null) {
-            return null;
-        }
-        BitmapFactory.Options o = new BitmapFactory.Options();
-        o.inJustDecodeBounds = true;
-        BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
-        if (o.outWidth == 0 || o.outHeight == 0) {
-            return null;
-        }
-        o.inBitmap = GalleryBitmapPool.getInstance().get(o.outWidth, o.outHeight);
-        o.inMutable = true;
-        o.inJustDecodeBounds = false;
-        o.inSampleSize = 1;
-        try {
-            return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
-        } catch (IllegalArgumentException e) {
-            // BitmapFactory throws an exception rather than returning null
-            // when image decoding fails and an existing bitmap was supplied
-            // for recycling, even if the failure was not caused by the use
-            // of that bitmap.
-            return BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
-        }
-    }
+    int orientation = Exif.getOrientation(imageBytes);
+    return new BitmapWithMetadata(created, orientation);
+  }
 
-    public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info) {
-        return getFullsize(device, info, sMaxSize);
-    }
-
-    public static BitmapWithMetadata getFullsize(MtpDevice device, MtpObjectInfo info, int maxSide) {
-        byte[] imageBytes = device.getObject(info.getObjectHandle(), info.getCompressedSize());
-        if (imageBytes == null) {
-            return null;
-        }
-        Bitmap created;
-        if (maxSide > 0) {
-            BitmapFactory.Options o = new BitmapFactory.Options();
-            o.inJustDecodeBounds = true;
-            BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
-            int w = o.outWidth;
-            int h = o.outHeight;
-            int comp = Math.max(h, w);
-            int sampleSize = 1;
-            while ((comp >> 1) >= maxSide) {
-                comp = comp >> 1;
-                sampleSize++;
-            }
-            o.inSampleSize = sampleSize;
-            o.inJustDecodeBounds = false;
-            created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length, o);
-        } else {
-            created = BitmapFactory.decodeByteArray(imageBytes, 0, imageBytes.length);
-        }
-        if (created == null) {
-            return null;
-        }
-
-        return new BitmapWithMetadata(created, Exif.getOrientation(imageBytes));
-    }
-
-    public static void configureForContext(Context context) {
-        DisplayMetrics metrics = new DisplayMetrics();
-        WindowManager wm = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);
-        wm.getDefaultDisplay().getMetrics(metrics);
-        sMaxSize = Math.max(metrics.heightPixels, metrics.widthPixels);
-    }
+  public static void configureForContext(Context context) {
+    DisplayMetrics metrics = new DisplayMetrics();
+    WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
+    wm.getDefaultDisplay().getMetrics(metrics);
+    sMaxSize = Math.max(metrics.heightPixels, metrics.widthPixels);
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/data/MtpClient.java b/src/com/android/gallery3d/ingest/data/MtpClient.java
new file mode 100644
index 0000000..cc6c9ce
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/MtpClient.java
@@ -0,0 +1,266 @@
+/*
+ * Copyright (C) 2010 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.app.PendingIntent;
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.hardware.usb.UsbConstants;
+import android.hardware.usb.UsbDevice;
+import android.hardware.usb.UsbDeviceConnection;
+import android.hardware.usb.UsbInterface;
+import android.hardware.usb.UsbManager;
+import android.mtp.MtpDevice;
+import android.os.Build;
+import android.util.Log;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+/**
+ * This class helps an application manage a list of connected MTP or PTP devices.
+ * It listens for MTP devices being attached and removed from the USB host bus
+ * and notifies the application when the MTP device list changes.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class MtpClient {
+
+  private static final String TAG = "MtpClient";
+
+  private static final String ACTION_USB_PERMISSION =
+      "com.android.gallery3d.ingest.action.USB_PERMISSION";
+
+  private final Context mContext;
+  private final UsbManager mUsbManager;
+  private final ArrayList<Listener> mListeners = new ArrayList<Listener>();
+  // mDevices contains all MtpDevices that have been seen by our client,
+  // so we can inform when the device has been detached.
+  // mDevices is also used for synchronization in this class.
+  private final HashMap<String, MtpDevice> mDevices = new HashMap<String, MtpDevice>();
+  // List of MTP devices we should not try to open for which we are currently
+  // asking for permission to open.
+  private final ArrayList<String> mRequestPermissionDevices = new ArrayList<String>();
+  // List of MTP devices we should not try to open.
+  // We add devices to this list if the user canceled a permission request or we were
+  // unable to open the device.
+  private final ArrayList<String> mIgnoredDevices = new ArrayList<String>();
+
+  private final PendingIntent mPermissionIntent;
+
+  private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {
+    @Override
+    public void onReceive(Context context, Intent intent) {
+      String action = intent.getAction();
+      UsbDevice usbDevice = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
+      String deviceName = usbDevice.getDeviceName();
+
+      synchronized (mDevices) {
+        MtpDevice mtpDevice = mDevices.get(deviceName);
+
+        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
+          if (mtpDevice == null) {
+            mtpDevice = openDeviceLocked(usbDevice);
+          }
+          if (mtpDevice != null) {
+            for (Listener listener : mListeners) {
+              listener.deviceAdded(mtpDevice);
+            }
+          }
+        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
+          if (mtpDevice != null) {
+            mDevices.remove(deviceName);
+            mRequestPermissionDevices.remove(deviceName);
+            mIgnoredDevices.remove(deviceName);
+            for (Listener listener : mListeners) {
+              listener.deviceRemoved(mtpDevice);
+            }
+          }
+        } else if (ACTION_USB_PERMISSION.equals(action)) {
+          mRequestPermissionDevices.remove(deviceName);
+          boolean permission = intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED,
+              false);
+          Log.d(TAG, "ACTION_USB_PERMISSION: " + permission);
+          if (permission) {
+            if (mtpDevice == null) {
+              mtpDevice = openDeviceLocked(usbDevice);
+            }
+            if (mtpDevice != null) {
+              for (Listener listener : mListeners) {
+                listener.deviceAdded(mtpDevice);
+              }
+            }
+          } else {
+            // so we don't ask for permission again
+            mIgnoredDevices.add(deviceName);
+          }
+        }
+      }
+    }
+  };
+
+  /**
+   * An interface for being notified when MTP or PTP devices are attached
+   * or removed.  In the current implementation, only PTP devices are supported.
+   */
+  public interface Listener {
+    /**
+     * Called when a new device has been added
+     *
+     * @param device the new device that was added
+     */
+    public void deviceAdded(MtpDevice device);
+
+    /**
+     * Called when a new device has been removed
+     *
+     * @param device the device that was removed
+     */
+    public void deviceRemoved(MtpDevice device);
+  }
+
+  /**
+   * Tests to see if a {@link android.hardware.usb.UsbDevice}
+   * supports the PTP protocol (typically used by digital cameras)
+   *
+   * @param device the device to test
+   * @return true if the device is a PTP device.
+   */
+  public static boolean isCamera(UsbDevice device) {
+    int count = device.getInterfaceCount();
+    for (int i = 0; i < count; i++) {
+      UsbInterface intf = device.getInterface(i);
+      if (intf.getInterfaceClass() == UsbConstants.USB_CLASS_STILL_IMAGE &&
+          intf.getInterfaceSubclass() == 1 &&
+          intf.getInterfaceProtocol() == 1) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /**
+   * MtpClient constructor
+   *
+   * @param context the {@link android.content.Context} to use for the MtpClient
+   */
+  public MtpClient(Context context) {
+    mContext = context;
+    mUsbManager = (UsbManager) context.getSystemService(Context.USB_SERVICE);
+    mPermissionIntent = PendingIntent.getBroadcast(mContext, 0,
+        new Intent(ACTION_USB_PERMISSION), 0);
+    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
+    filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
+    filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
+    filter.addAction(ACTION_USB_PERMISSION);
+    context.registerReceiver(mUsbReceiver, filter);
+  }
+
+  /**
+   * Opens the {@link android.hardware.usb.UsbDevice} for an MTP or PTP
+   * device and return an {@link android.mtp.MtpDevice} for it.
+   *
+   * @param usbDevice the device to open
+   * @return an MtpDevice for the device.
+   */
+  private MtpDevice openDeviceLocked(UsbDevice usbDevice) {
+    String deviceName = usbDevice.getDeviceName();
+
+    // don't try to open devices that we have decided to ignore
+    // or are currently asking permission for
+    if (isCamera(usbDevice) && !mIgnoredDevices.contains(deviceName)
+        && !mRequestPermissionDevices.contains(deviceName)) {
+      if (!mUsbManager.hasPermission(usbDevice)) {
+        mUsbManager.requestPermission(usbDevice, mPermissionIntent);
+        mRequestPermissionDevices.add(deviceName);
+      } else {
+        UsbDeviceConnection connection = mUsbManager.openDevice(usbDevice);
+        if (connection != null) {
+          MtpDevice mtpDevice = new MtpDevice(usbDevice);
+          if (mtpDevice.open(connection)) {
+            mDevices.put(usbDevice.getDeviceName(), mtpDevice);
+            return mtpDevice;
+          } else {
+            // so we don't try to open it again
+            mIgnoredDevices.add(deviceName);
+          }
+        } else {
+          // so we don't try to open it again
+          mIgnoredDevices.add(deviceName);
+        }
+      }
+    }
+    return null;
+  }
+
+  /**
+   * Closes all resources related to the MtpClient object
+   */
+  public void close() {
+    mContext.unregisterReceiver(mUsbReceiver);
+  }
+
+  /**
+   * Registers a {@link com.android.gallery3d.data.MtpClient.Listener} interface to receive
+   * notifications when MTP or PTP devices are added or removed.
+   *
+   * @param listener the listener to register
+   */
+  public void addListener(Listener listener) {
+    synchronized (mDevices) {
+      if (!mListeners.contains(listener)) {
+        mListeners.add(listener);
+      }
+    }
+  }
+
+  /**
+   * Unregisters a {@link com.android.gallery3d.data.MtpClient.Listener} interface.
+   *
+   * @param listener the listener to unregister
+   */
+  public void removeListener(Listener listener) {
+    synchronized (mDevices) {
+      mListeners.remove(listener);
+    }
+  }
+
+
+  /**
+   * Retrieves a list of all currently connected {@link android.mtp.MtpDevice}.
+   *
+   * @return the list of MtpDevices
+   */
+  public List<MtpDevice> getDeviceList() {
+    synchronized (mDevices) {
+      // Query the USB manager since devices might have attached
+      // before we added our listener.
+      for (UsbDevice usbDevice : mUsbManager.getDeviceList().values()) {
+        if (mDevices.get(usbDevice.getDeviceName()) == null) {
+          openDeviceLocked(usbDevice);
+        }
+      }
+
+      return new ArrayList<MtpDevice>(mDevices.values());
+    }
+  }
+
+
+}
diff --git a/src/com/android/gallery3d/ingest/data/MtpDeviceIndex.java b/src/com/android/gallery3d/ingest/data/MtpDeviceIndex.java
new file mode 100644
index 0000000..b21ad83
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/MtpDeviceIndex.java
@@ -0,0 +1,433 @@
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.mtp.MtpConstants;
+import android.mtp.MtpDevice;
+import android.os.Build;
+
+import java.util.Collections;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Index of MTP media objects organized into "buckets," or groupings, based on the date
+ * they were created.
+ *
+ * When the index is created, the buckets are sorted in their natural
+ * order, and the items within the buckets sorted by the date they are taken.
+ *
+ * The index enables the access of items and bucket labels as one unified list.
+ * For example, let's say we have the following data in the index:
+ *    [Bucket A]: [photo 1], [photo 2]
+ *    [Bucket B]: [photo 3]
+ *
+ * Then the items can be thought of as being organized as a 5 element list:
+ *   [Bucket A], [photo 1], [photo 2], [Bucket B], [photo 3]
+ *
+ * The data can also be accessed in descending order, in which case the list
+ * would be a bit different from simply reversing the ascending list, since the
+ * bucket labels need to always be at the beginning:
+ *   [Bucket B], [photo 3], [Bucket A], [photo 2], [photo 1]
+ *
+ * The index enables all the following operations in constant time, both for
+ * ascending and descending views of the data:
+ *   - get/getAscending/getDescending: get an item at a specified list position
+ *   - size: get the total number of items (bucket labels and MTP objects)
+ *   - getFirstPositionForBucketNumber
+ *   - getBucketNumberForPosition
+ *   - isFirstInBucket
+ *
+ * See {@link MtpDeviceIndexRunnable} for implementation notes.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class MtpDeviceIndex {
+
+  /**
+   * Indexing progress listener.
+   */
+  public interface ProgressListener {
+    /**
+     * A media item on the device was indexed.
+     * @param object The media item that was just indexed
+     * @param numVisited Number of items visited so far
+     */
+    public void onObjectIndexed(IngestObjectInfo object, int numVisited);
+
+    /**
+     * The metadata loaded from the device is being sorted.
+     */
+    public void onSortingStarted();
+
+    /**
+     * The indexing is done and the index is ready to be used.
+     */
+    public void onIndexingFinished();
+  }
+
+  /**
+   * Media sort orders.
+   */
+  public enum SortOrder {
+    ASCENDING, DESCENDING
+  }
+
+  /** Quicktime MOV container (not already defined in {@link MtpConstants}) **/
+  public static final int FORMAT_MOV = 0x300D;
+
+  public static final Set<Integer> SUPPORTED_IMAGE_FORMATS;
+  public static final Set<Integer> SUPPORTED_VIDEO_FORMATS;
+
+  static {
+    Set<Integer> supportedImageFormats = new HashSet<Integer>();
+    supportedImageFormats.add(MtpConstants.FORMAT_JFIF);
+    supportedImageFormats.add(MtpConstants.FORMAT_EXIF_JPEG);
+    supportedImageFormats.add(MtpConstants.FORMAT_PNG);
+    supportedImageFormats.add(MtpConstants.FORMAT_GIF);
+    supportedImageFormats.add(MtpConstants.FORMAT_BMP);
+    SUPPORTED_IMAGE_FORMATS = Collections.unmodifiableSet(supportedImageFormats);
+
+    Set<Integer> supportedVideoFormats = new HashSet<Integer>();
+    supportedVideoFormats.add(MtpConstants.FORMAT_3GP_CONTAINER);
+    supportedVideoFormats.add(MtpConstants.FORMAT_AVI);
+    supportedVideoFormats.add(MtpConstants.FORMAT_MP4_CONTAINER);
+    supportedVideoFormats.add(MtpConstants.FORMAT_MPEG);
+    // TODO(georgescu): add FORMAT_MOV once Android Media Scanner supports .mov files
+    SUPPORTED_VIDEO_FORMATS = Collections.unmodifiableSet(supportedVideoFormats);
+  }
+
+  private MtpDevice mDevice;
+  private long mGeneration;
+  private ProgressListener mProgressListener;
+  private volatile MtpDeviceIndexRunnable.Results mResults;
+  private final MtpDeviceIndexRunnable.Factory mIndexRunnableFactory;
+
+  private static final MtpDeviceIndex sInstance = new MtpDeviceIndex(
+      MtpDeviceIndexRunnable.getFactory());
+
+  public static MtpDeviceIndex getInstance() {
+    return sInstance;
+  }
+
+  protected MtpDeviceIndex(MtpDeviceIndexRunnable.Factory indexRunnableFactory) {
+    mIndexRunnableFactory = indexRunnableFactory;
+  }
+
+  public synchronized MtpDevice getDevice() {
+    return mDevice;
+  }
+
+  public synchronized boolean isDeviceConnected() {
+    return (mDevice != null);
+  }
+
+  /**
+   * @param format Media format from {@link MtpConstants}
+   * @return Whether the format is supported by this index.
+   */
+  public boolean isFormatSupported(int format) {
+    return SUPPORTED_IMAGE_FORMATS.contains(format)
+        || SUPPORTED_VIDEO_FORMATS.contains(format);
+  }
+
+  /**
+   * Sets the MtpDevice that should be indexed and initializes state, but does
+   * not kick off the actual indexing task, which is instead done by using
+   * {@link #getIndexRunnable()}
+   *
+   * @param device The MtpDevice that should be indexed
+   */
+  public synchronized void setDevice(MtpDevice device) {
+    if (device == mDevice) {
+      return;
+    }
+    mDevice = device;
+    resetState();
+  }
+
+  /**
+   * Provides a Runnable for the indexing task (assuming the state has already
+   * been correctly initialized by calling {@link #setDevice(MtpDevice)}).
+   *
+   * @return Runnable for the main indexing task
+   */
+  public synchronized Runnable getIndexRunnable() {
+    if (!isDeviceConnected() || mResults != null) {
+      return null;
+    }
+    return mIndexRunnableFactory.createMtpDeviceIndexRunnable(this);
+  }
+
+  /**
+   * @return Whether the index is ready to be used.
+   */
+  public synchronized boolean isIndexReady() {
+    return mResults != null;
+  }
+
+  /**
+   * @param listener
+   * @return Current progress (useful for configuring initial UI state)
+   */
+  public synchronized void setProgressListener(ProgressListener listener) {
+    mProgressListener = listener;
+  }
+
+  /**
+   * Make the listener null if it matches the argument
+   *
+   * @param listener Listener to unset, if currently registered
+   */
+  public synchronized void unsetProgressListener(ProgressListener listener) {
+    if (mProgressListener == listener) {
+      mProgressListener = null;
+    }
+  }
+
+  /**
+   * @return The total number of elements in the index (labels and items)
+   */
+  public int size() {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    return results != null ? results.unifiedLookupIndex.length : 0;
+  }
+
+  /**
+   * @param position Index of item to fetch, where 0 is the first item in the
+   *            specified order
+   * @param order
+   * @return the bucket label or IngestObjectInfo at the specified position and
+   *         order
+   */
+  public Object get(int position, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (results == null) {
+      return null;
+    }
+    if (order == SortOrder.ASCENDING) {
+      DateBucket bucket = results.buckets[results.unifiedLookupIndex[position]];
+      if (bucket.unifiedStartIndex == position) {
+        return bucket.date;
+      } else {
+        return results.mtpObjects[bucket.itemsStartIndex + position - 1
+            - bucket.unifiedStartIndex];
+      }
+    } else {
+      int zeroIndex = results.unifiedLookupIndex.length - 1 - position;
+      DateBucket bucket = results.buckets[results.unifiedLookupIndex[zeroIndex]];
+      if (bucket.unifiedEndIndex == zeroIndex) {
+        return bucket.date;
+      } else {
+        return results.mtpObjects[bucket.itemsStartIndex + zeroIndex
+            - bucket.unifiedStartIndex];
+      }
+    }
+  }
+
+  /**
+   * @param position Index of item to fetch from a view of the data that does not
+   *            include labels and is in the specified order
+   * @return position-th item in specified order, when not including labels
+   */
+  public IngestObjectInfo getWithoutLabels(int position, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (results == null) {
+      return null;
+    }
+    if (order == SortOrder.ASCENDING) {
+      return results.mtpObjects[position];
+    } else {
+      return results.mtpObjects[results.mtpObjects.length - 1 - position];
+    }
+  }
+
+  /**
+   * @param position Index of item to map from a view of the data that does not
+   *            include labels and is in the specified order
+   * @param order
+   * @return position in a view of the data that does include labels, or -1 if the index isn't
+   *         ready
+   */
+  public int getPositionFromPositionWithoutLabels(int position, SortOrder order) {
+        /* Although this is O(log(number of buckets)), and thus should not be used
+           in hotspots, even if the attached device has items for every day for
+           a five-year timeframe, it would still only take 11 iterations at most,
+           so shouldn't be a huge issue. */
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (results == null) {
+      return -1;
+    }
+    if (order == SortOrder.DESCENDING) {
+      position = results.mtpObjects.length - 1 - position;
+    }
+    int bucketNumber = 0;
+    int iMin = 0;
+    int iMax = results.buckets.length - 1;
+    while (iMax >= iMin) {
+      int iMid = (iMax + iMin) / 2;
+      if (results.buckets[iMid].itemsStartIndex + results.buckets[iMid].numItems
+          <= position) {
+        iMin = iMid + 1;
+      } else if (results.buckets[iMid].itemsStartIndex > position) {
+        iMax = iMid - 1;
+      } else {
+        bucketNumber = iMid;
+        break;
+      }
+    }
+    int mappedPos = results.buckets[bucketNumber].unifiedStartIndex + position
+        - results.buckets[bucketNumber].itemsStartIndex + 1;
+    if (order == SortOrder.DESCENDING) {
+      mappedPos = results.unifiedLookupIndex.length - mappedPos;
+    }
+    return mappedPos;
+  }
+
+  /**
+   * @param position Index of item to map from a view of the data that
+   *            includes labels and is in the specified order
+   * @param order
+   * @return position in a view of the data that does not include labels, or -1 if the index isn't
+   *         ready
+   */
+  public int getPositionWithoutLabelsFromPosition(int position, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (results == null) {
+      return -1;
+    }
+    if (order == SortOrder.ASCENDING) {
+      DateBucket bucket = results.buckets[results.unifiedLookupIndex[position]];
+      if (bucket.unifiedStartIndex == position) {
+        position++;
+      }
+      return bucket.itemsStartIndex + position - 1 - bucket.unifiedStartIndex;
+    } else {
+      int zeroIndex = results.unifiedLookupIndex.length - 1 - position;
+      DateBucket bucket = results.buckets[results.unifiedLookupIndex[zeroIndex]];
+      if (bucket.unifiedEndIndex == zeroIndex) {
+        zeroIndex--;
+      }
+      return results.mtpObjects.length - 1 - bucket.itemsStartIndex
+          - zeroIndex + bucket.unifiedStartIndex;
+    }
+  }
+
+  /**
+   * @return The number of media items in the index
+   */
+  public int sizeWithoutLabels() {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    return results != null ? results.mtpObjects.length : 0;
+  }
+
+  /**
+   * @param bucketNumber Index of bucket in the specified order
+   * @param order
+   * @return position of bucket's first item in a view of the data that includes labels
+   */
+  public int getFirstPositionForBucketNumber(int bucketNumber, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (order == SortOrder.ASCENDING) {
+      return results.buckets[bucketNumber].unifiedStartIndex;
+    } else {
+      return results.unifiedLookupIndex.length
+          - results.buckets[results.buckets.length - 1 - bucketNumber].unifiedEndIndex
+          - 1;
+    }
+  }
+
+  /**
+   * @param position Index of item in the view of the data that includes labels and is in
+   *                 the specified order
+   * @param order
+   * @return Index of the bucket that contains the specified item
+   */
+  public int getBucketNumberForPosition(int position, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (order == SortOrder.ASCENDING) {
+      return results.unifiedLookupIndex[position];
+    } else {
+      return results.buckets.length - 1
+          - results.unifiedLookupIndex[results.unifiedLookupIndex.length - 1
+          - position];
+    }
+  }
+
+  /**
+   * @param position Index of item in the view of the data that includes labels and is in
+   *                 the specified order
+   * @param order
+   * @return Whether the specified item is the first item in its bucket
+   */
+  public boolean isFirstInBucket(int position, SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (order == SortOrder.ASCENDING) {
+      return results.buckets[results.unifiedLookupIndex[position]].unifiedStartIndex
+          == position;
+    } else {
+      position = results.unifiedLookupIndex.length - 1 - position;
+      return results.buckets[results.unifiedLookupIndex[position]].unifiedEndIndex
+          == position;
+    }
+  }
+
+  /**
+   * @param order
+   * @return Array of buckets in the specified order
+   */
+  public DateBucket[] getBuckets(SortOrder order) {
+    MtpDeviceIndexRunnable.Results results = mResults;
+    if (results == null) {
+      return null;
+    }
+    return (order == SortOrder.ASCENDING) ? results.buckets : results.reversedBuckets;
+  }
+
+  protected void resetState() {
+    mGeneration++;
+    mResults = null;
+  }
+
+  /**
+   * @param device
+   * @param generation
+   * @return whether the index is at the given generation and the given device is connected
+   */
+  protected boolean isAtGeneration(MtpDevice device, long generation) {
+    return (mGeneration == generation) && (mDevice == device);
+  }
+
+  protected synchronized boolean setIndexingResults(MtpDevice device, long generation,
+      MtpDeviceIndexRunnable.Results results) {
+    if (!isAtGeneration(device, generation)) {
+      return false;
+    }
+    mResults = results;
+    onIndexFinish(true /*successful*/);
+    return true;
+  }
+
+  protected synchronized void onIndexFinish(boolean successful) {
+    if (!successful) {
+      resetState();
+    }
+    if (mProgressListener != null) {
+      mProgressListener.onIndexingFinished();
+    }
+  }
+
+  protected synchronized void onSorting() {
+    if (mProgressListener != null) {
+      mProgressListener.onSortingStarted();
+    }
+  }
+
+  protected synchronized void onObjectIndexed(IngestObjectInfo object, int numVisited) {
+    if (mProgressListener != null) {
+      mProgressListener.onObjectIndexed(object, numVisited);
+    }
+  }
+
+  protected long getGeneration() {
+    return mGeneration;
+  }
+}
diff --git a/src/com/android/gallery3d/ingest/data/MtpDeviceIndexRunnable.java b/src/com/android/gallery3d/ingest/data/MtpDeviceIndexRunnable.java
new file mode 100644
index 0000000..3227589
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/MtpDeviceIndexRunnable.java
@@ -0,0 +1,186 @@
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.mtp.MtpConstants;
+import android.mtp.MtpDevice;
+import android.mtp.MtpObjectInfo;
+import android.os.Build;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.SortedMap;
+import java.util.Stack;
+import java.util.TreeMap;
+
+/**
+ * Runnable used by the {@link MtpDeviceIndex} to populate its index.
+ *
+ * Implementation note: this is the way the index supports a lot of its operations in
+ * constant time and respecting the need to have bucket names always come before items
+ * in that bucket when accessing the list sequentially, both in ascending and descending
+ * orders.
+ *
+ * Let's say the data we have in the index is the following:
+ *  [Bucket A]: [photo 1], [photo 2]
+ *  [Bucket B]: [photo 3]
+ *
+ *  In this case, the lookup index array would be
+ *  [0, 0, 0, 1, 1]
+ *
+ *  Now, whether we access the list in ascending or descending order, we know which bucket
+ *  to look in (0 corresponds to A and 1 to B), and can return the bucket label as the first
+ *  item in a bucket as needed. The individual IndexBUckets have a startIndex and endIndex
+ *  that correspond to indices in this lookup index array, allowing us to calculate the
+ *  offset of the specific item we want from within a specific bucket.
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class MtpDeviceIndexRunnable implements Runnable {
+
+  /**
+   * MtpDeviceIndexRunnable factory.
+   */
+  public static class Factory {
+    public MtpDeviceIndexRunnable createMtpDeviceIndexRunnable(MtpDeviceIndex index) {
+      return new MtpDeviceIndexRunnable(index);
+    }
+  }
+
+  static class Results {
+    final int[] unifiedLookupIndex;
+    final IngestObjectInfo[] mtpObjects;
+    final DateBucket[] buckets;
+    final DateBucket[] reversedBuckets;
+
+    public Results(
+        int[] unifiedLookupIndex, IngestObjectInfo[] mtpObjects, DateBucket[] buckets) {
+      this.unifiedLookupIndex = unifiedLookupIndex;
+      this.mtpObjects = mtpObjects;
+      this.buckets = buckets;
+      this.reversedBuckets = new DateBucket[buckets.length];
+      for (int i = 0; i < buckets.length; i++) {
+        this.reversedBuckets[i] = buckets[buckets.length - 1 - i];
+      }
+    }
+  }
+
+  private final MtpDevice mDevice;
+  protected final MtpDeviceIndex mIndex;
+  private final long mIndexGeneration;
+
+  private static Factory sDefaultFactory = new Factory();
+
+  public static Factory getFactory() {
+    return sDefaultFactory;
+  }
+
+  /**
+   * Exception thrown when a problem occurred during indexing.
+   */
+  @SuppressWarnings("serial")
+  public class IndexingException extends RuntimeException {}
+
+  MtpDeviceIndexRunnable(MtpDeviceIndex index) {
+    mIndex = index;
+    mDevice = index.getDevice();
+    mIndexGeneration = index.getGeneration();
+  }
+
+  @Override
+  public void run() {
+    try {
+      indexDevice();
+    } catch (IndexingException e) {
+      mIndex.onIndexFinish(false /*successful*/);
+    }
+  }
+
+  private void indexDevice() throws IndexingException {
+    SortedMap<SimpleDate, List<IngestObjectInfo>> bucketsTemp =
+        new TreeMap<SimpleDate, List<IngestObjectInfo>>();
+    int numObjects = addAllObjects(bucketsTemp);
+    mIndex.onSorting();
+    int numBuckets = bucketsTemp.size();
+    DateBucket[] buckets = new DateBucket[numBuckets];
+    IngestObjectInfo[] mtpObjects = new IngestObjectInfo[numObjects];
+    int[] unifiedLookupIndex = new int[numObjects + numBuckets];
+    int currentUnifiedIndexEntry = 0;
+    int currentItemsEntry = 0;
+    int nextUnifiedEntry, unifiedStartIndex, numBucketObjects, unifiedEndIndex, itemsStartIndex;
+
+    int i = 0;
+    for (Map.Entry<SimpleDate, List<IngestObjectInfo>> bucketTemp : bucketsTemp.entrySet()) {
+      List<IngestObjectInfo> objects = bucketTemp.getValue();
+      Collections.sort(objects);
+      numBucketObjects = objects.size();
+
+      nextUnifiedEntry = currentUnifiedIndexEntry + numBucketObjects + 1;
+      Arrays.fill(unifiedLookupIndex, currentUnifiedIndexEntry, nextUnifiedEntry, i);
+      unifiedStartIndex = currentUnifiedIndexEntry;
+      unifiedEndIndex = nextUnifiedEntry - 1;
+      currentUnifiedIndexEntry = nextUnifiedEntry;
+
+      itemsStartIndex = currentItemsEntry;
+      for (int j = 0; j < numBucketObjects; j++) {
+        mtpObjects[currentItemsEntry] = objects.get(j);
+        currentItemsEntry++;
+      }
+      buckets[i] = new DateBucket(bucketTemp.getKey(), unifiedStartIndex, unifiedEndIndex,
+          itemsStartIndex, numBucketObjects);
+      i++;
+    }
+    if (!mIndex.setIndexingResults(mDevice, mIndexGeneration,
+        new Results(unifiedLookupIndex, mtpObjects, buckets))) {
+      throw new IndexingException();
+    }
+  }
+
+  private SimpleDate mDateInstance = new SimpleDate();
+
+  protected void addObject(IngestObjectInfo objectInfo,
+      SortedMap<SimpleDate, List<IngestObjectInfo>> bucketsTemp, int numObjects) {
+    mDateInstance.setTimestamp(objectInfo.getDateCreated());
+    List<IngestObjectInfo> bucket = bucketsTemp.get(mDateInstance);
+    if (bucket == null) {
+      bucket = new ArrayList<IngestObjectInfo>();
+      bucketsTemp.put(mDateInstance, bucket);
+      mDateInstance = new SimpleDate(); // only create new date objects when they are used
+    }
+    bucket.add(objectInfo);
+    mIndex.onObjectIndexed(objectInfo, numObjects);
+  }
+
+  protected int addAllObjects(SortedMap<SimpleDate, List<IngestObjectInfo>> bucketsTemp)
+      throws IndexingException {
+    int numObjects = 0;
+    for (int storageId : mDevice.getStorageIds()) {
+      if (!mIndex.isAtGeneration(mDevice, mIndexGeneration)) {
+        throw new IndexingException();
+      }
+      Stack<Integer> pendingDirectories = new Stack<Integer>();
+      pendingDirectories.add(0xFFFFFFFF); // start at the root of the device
+      while (!pendingDirectories.isEmpty()) {
+        if (!mIndex.isAtGeneration(mDevice, mIndexGeneration)) {
+          throw new IndexingException();
+        }
+        int dirHandle = pendingDirectories.pop();
+        for (int objectHandle : mDevice.getObjectHandles(storageId, 0, dirHandle)) {
+          MtpObjectInfo mtpObjectInfo = mDevice.getObjectInfo(objectHandle);
+          if (mtpObjectInfo == null) {
+            throw new IndexingException();
+          }
+          int format = mtpObjectInfo.getFormat();
+          if (format == MtpConstants.FORMAT_ASSOCIATION) {
+            pendingDirectories.add(objectHandle);
+          } else if (mIndex.isFormatSupported(format)) {
+            numObjects++;
+            addObject(new IngestObjectInfo(mtpObjectInfo), bucketsTemp, numObjects);
+          }
+        }
+      }
+    }
+    return numObjects;
+  }
+}
diff --git a/src/com/android/gallery3d/ingest/data/SimpleDate.java b/src/com/android/gallery3d/ingest/data/SimpleDate.java
new file mode 100644
index 0000000..2476f80
--- /dev/null
+++ b/src/com/android/gallery3d/ingest/data/SimpleDate.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.gallery3d.ingest.data;
+
+import android.annotation.TargetApi;
+import android.os.Build;
+
+import java.text.DateFormat;
+import java.util.Calendar;
+
+/**
+ * Represents a date (year, month, day)
+ */
+@TargetApi(Build.VERSION_CODES.HONEYCOMB_MR1)
+public class SimpleDate implements Comparable<SimpleDate> {
+  public int month; // MM
+  public int day; // DD
+  public int year; // YYYY
+  private long timestamp;
+  private String mCachedStringRepresentation;
+
+  public SimpleDate() {
+  }
+
+  public SimpleDate(long timestamp) {
+    setTimestamp(timestamp);
+  }
+
+  private static Calendar sCalendarInstance = Calendar.getInstance();
+
+  public void setTimestamp(long timestamp) {
+    synchronized (sCalendarInstance) {
+      // TODO(georgescu): find a more efficient way to convert a timestamp to a date?
+      sCalendarInstance.setTimeInMillis(timestamp);
+      this.day = sCalendarInstance.get(Calendar.DATE);
+      this.month = sCalendarInstance.get(Calendar.MONTH);
+      this.year = sCalendarInstance.get(Calendar.YEAR);
+      this.timestamp = timestamp;
+      mCachedStringRepresentation =
+          DateFormat.getDateInstance(DateFormat.SHORT).format(timestamp);
+    }
+  }
+
+  @Override
+  public int hashCode() {
+    final int prime = 31;
+    int result = 1;
+    result = prime * result + day;
+    result = prime * result + month;
+    result = prime * result + year;
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    if (this == obj) {
+      return true;
+    }
+    if (obj == null) {
+      return false;
+    }
+    if (!(obj instanceof SimpleDate)) {
+      return false;
+    }
+    SimpleDate other = (SimpleDate) obj;
+    if (year != other.year) {
+      return false;
+    }
+    if (month != other.month) {
+      return false;
+    }
+    if (day != other.day) {
+      return false;
+    }
+    return true;
+  }
+
+  @Override
+  public int compareTo(SimpleDate other) {
+    int yearDiff = this.year - other.getYear();
+    if (yearDiff != 0) {
+      return yearDiff;
+    } else {
+      int monthDiff = this.month - other.getMonth();
+      if (monthDiff != 0) {
+        return monthDiff;
+      } else {
+        return this.day - other.getDay();
+      }
+    }
+  }
+
+  public int getDay() {
+    return day;
+  }
+
+  public int getMonth() {
+    return month;
+  }
+
+  public int getYear() {
+    return year;
+  }
+
+  @Override
+  public String toString() {
+    if (mCachedStringRepresentation == null) {
+      mCachedStringRepresentation =
+          DateFormat.getDateInstance(DateFormat.SHORT).format(timestamp);
+    }
+    return mCachedStringRepresentation;
+  }
+}
diff --git a/src/com/android/gallery3d/ingest/ui/DateTileView.java b/src/com/android/gallery3d/ingest/ui/DateTileView.java
index 52fe9b8..cd31e82 100644
--- a/src/com/android/gallery3d/ingest/ui/DateTileView.java
+++ b/src/com/android/gallery3d/ingest/ui/DateTileView.java
@@ -16,92 +16,96 @@
 
 package com.android.gallery3d.ingest.ui;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.SimpleDate;
+
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.FrameLayout;
 import android.widget.TextView;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.SimpleDate;
 
 import java.text.DateFormatSymbols;
 import java.util.Locale;
 
+/**
+ * Displays a date in a square tile.
+ */
 public class DateTileView extends FrameLayout {
-    private static String[] sMonthNames = DateFormatSymbols.getInstance().getShortMonths();
-    private static Locale sLocale;
+  private static String[] sMonthNames = DateFormatSymbols.getInstance().getShortMonths();
+  private static Locale sLocale;
 
-    static {
-        refreshLocale();
+  static {
+    refreshLocale();
+  }
+
+  public static boolean refreshLocale() {
+    Locale currentLocale = Locale.getDefault();
+    if (!currentLocale.equals(sLocale)) {
+      sLocale = currentLocale;
+      sMonthNames = DateFormatSymbols.getInstance(sLocale).getShortMonths();
+      return true;
+    } else {
+      return false;
     }
+  }
 
-    public static boolean refreshLocale() {
-        Locale currentLocale = Locale.getDefault();
-        if (!currentLocale.equals(sLocale)) {
-            sLocale = currentLocale;
-            sMonthNames = DateFormatSymbols.getInstance(sLocale).getShortMonths();
-            return true;
-        } else {
-            return false;
-        }
+  private TextView mDateTextView;
+  private TextView mMonthTextView;
+  private TextView mYearTextView;
+  private int mMonth = -1;
+  private int mYear = -1;
+  private int mDate = -1;
+  private String[] mMonthNames = sMonthNames;
+
+  public DateTileView(Context context) {
+    super(context);
+  }
+
+  public DateTileView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+  }
+
+  public DateTileView(Context context, AttributeSet attrs, int defStyle) {
+    super(context, attrs, defStyle);
+  }
+
+  @Override
+  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+    // Force this to be square
+    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
+  }
+
+  @Override
+  protected void onFinishInflate() {
+    super.onFinishInflate();
+    mDateTextView = (TextView) findViewById(R.id.date_tile_day);
+    mMonthTextView = (TextView) findViewById(R.id.date_tile_month);
+    mYearTextView = (TextView) findViewById(R.id.date_tile_year);
+  }
+
+  public void setDate(SimpleDate date) {
+    setDate(date.getDay(), date.getMonth(), date.getYear());
+  }
+
+  public void setDate(int date, int month, int year) {
+    if (date != mDate) {
+      mDate = date;
+      mDateTextView.setText(mDate > 9 ? Integer.toString(mDate) : "0" + mDate);
     }
-
-    private TextView mDateTextView;
-    private TextView mMonthTextView;
-    private TextView mYearTextView;
-    private int mMonth = -1;
-    private int mYear = -1;
-    private int mDate = -1;
-    private String[] mMonthNames = sMonthNames;
-
-    public DateTileView(Context context) {
-        super(context);
+    if (mMonthNames != sMonthNames) {
+      mMonthNames = sMonthNames;
+      if (month == mMonth) {
+        mMonthTextView.setText(mMonthNames[mMonth]);
+      }
     }
-
-    public DateTileView(Context context, AttributeSet attrs) {
-        super(context, attrs);
+    if (month != mMonth) {
+      mMonth = month;
+      mMonthTextView.setText(mMonthNames[mMonth]);
     }
-
-    public DateTileView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
+    if (year != mYear) {
+      mYear = year;
+      mYearTextView.setText(Integer.toString(mYear));
     }
-
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Force this to be square
-        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
-    }
-
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mDateTextView = (TextView) findViewById(R.id.date_tile_day);
-        mMonthTextView = (TextView) findViewById(R.id.date_tile_month);
-        mYearTextView = (TextView) findViewById(R.id.date_tile_year);
-    }
-
-    public void setDate(SimpleDate date) {
-        setDate(date.getDay(), date.getMonth(), date.getYear());
-    }
-
-    public void setDate(int date, int month, int year) {
-        if (date != mDate) {
-            mDate = date;
-            mDateTextView.setText(mDate > 9 ? Integer.toString(mDate) : "0" + mDate);
-        }
-        if (mMonthNames != sMonthNames) {
-            mMonthNames = sMonthNames;
-            if (month == mMonth) {
-                mMonthTextView.setText(mMonthNames[mMonth]);
-            }
-        }
-        if (month != mMonth) {
-            mMonth = month;
-            mMonthTextView.setText(mMonthNames[mMonth]);
-        }
-        if (year != mYear) {
-            mYear = year;
-            mYearTextView.setText(Integer.toString(mYear));
-        }
-    }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/ui/IngestGridView.java b/src/com/android/gallery3d/ingest/ui/IngestGridView.java
index c821259..7bafa7c 100644
--- a/src/com/android/gallery3d/ingest/ui/IngestGridView.java
+++ b/src/com/android/gallery3d/ingest/ui/IngestGridView.java
@@ -21,38 +21,40 @@
 import android.widget.GridView;
 
 /**
- * This just extends GridView with the ability to listen for calls
- * to clearChoices()
+ * Extends GridView with the ability to listen for calls to clearChoices()
  */
 public class IngestGridView extends GridView {
 
-    public interface OnClearChoicesListener {
-        public void onClearChoices();
-    }
+  /**
+   * Listener for all checked choices being cleared.
+   */
+  public interface OnClearChoicesListener {
+    public void onClearChoices();
+  }
 
-    private OnClearChoicesListener mOnClearChoicesListener = null;
+  private OnClearChoicesListener mOnClearChoicesListener = null;
 
-    public IngestGridView(Context context) {
-        super(context);
-    }
+  public IngestGridView(Context context) {
+    super(context);
+  }
 
-    public IngestGridView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
+  public IngestGridView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+  }
 
-    public IngestGridView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
+  public IngestGridView(Context context, AttributeSet attrs, int defStyle) {
+    super(context, attrs, defStyle);
+  }
 
-    public void setOnClearChoicesListener(OnClearChoicesListener l) {
-        mOnClearChoicesListener = l;
-    }
+  public void setOnClearChoicesListener(OnClearChoicesListener l) {
+    mOnClearChoicesListener = l;
+  }
 
-    @Override
-    public void clearChoices() {
-        super.clearChoices();
-        if (mOnClearChoicesListener != null) {
-            mOnClearChoicesListener.onClearChoices();
-        }
+  @Override
+  public void clearChoices() {
+    super.clearChoices();
+    if (mOnClearChoicesListener != null) {
+      mOnClearChoicesListener.onClearChoices();
     }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java b/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java
index 8d3884d..00785dd 100644
--- a/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java
+++ b/src/com/android/gallery3d/ingest/ui/MtpFullscreenView.java
@@ -16,100 +16,106 @@
 
 package com.android.gallery3d.ingest.ui;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.adapter.CheckBroker;
+
 import android.content.Context;
 import android.util.AttributeSet;
 import android.widget.CheckBox;
 import android.widget.Checkable;
 import android.widget.CompoundButton;
-import android.widget.CompoundButton.OnCheckedChangeListener;
 import android.widget.RelativeLayout;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.adapter.CheckBroker;
-
+/**
+ * View for displaying an MTP-image and associated controls full-screen
+ */
 public class MtpFullscreenView extends RelativeLayout implements Checkable,
     CompoundButton.OnCheckedChangeListener, CheckBroker.OnCheckedChangedListener {
 
-    private MtpImageView mImageView;
-    private CheckBox mCheckbox;
-    private int mPosition = -1;
-    private CheckBroker mBroker;
+  private MtpImageView mImageView;
+  private CheckBox mCheckbox;
+  private int mPosition = -1;
+  private CheckBroker mBroker;
 
-    public MtpFullscreenView(Context context) {
-        super(context);
-    }
+  public MtpFullscreenView(Context context) {
+    super(context);
+  }
 
-    public MtpFullscreenView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
+  public MtpFullscreenView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+  }
 
-    public MtpFullscreenView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
+  public MtpFullscreenView(Context context, AttributeSet attrs, int defStyle) {
+    super(context, attrs, defStyle);
+  }
 
-    @Override
-    protected void onFinishInflate() {
-        super.onFinishInflate();
-        mImageView = (MtpImageView) findViewById(R.id.ingest_fullsize_image);
-        mCheckbox = (CheckBox) findViewById(R.id.ingest_fullsize_image_checkbox);
-        mCheckbox.setOnCheckedChangeListener(this);
-    }
+  @Override
+  protected void onFinishInflate() {
+    super.onFinishInflate();
+    mImageView = (MtpImageView) findViewById(R.id.ingest_fullsize_image);
+    mCheckbox = (CheckBox) findViewById(R.id.ingest_fullsize_image_checkbox);
+    mCheckbox.setOnCheckedChangeListener(this);
+  }
 
-    @Override
-    public boolean isChecked() {
-        return mCheckbox.isChecked();
-    }
+  @Override
+  public boolean isChecked() {
+    return mCheckbox.isChecked();
+  }
 
-    @Override
-    public void setChecked(boolean checked) {
-        mCheckbox.setChecked(checked);
-    }
+  @Override
+  public void setChecked(boolean checked) {
+    mCheckbox.setChecked(checked);
+  }
 
-    @Override
-    public void toggle() {
-        mCheckbox.toggle();
-    }
+  @Override
+  public void toggle() {
+    mCheckbox.toggle();
+  }
 
-    @Override
-    public void onDetachedFromWindow() {
-        setPositionAndBroker(-1, null);
-        super.onDetachedFromWindow();
-    }
+  @Override
+  public void onDetachedFromWindow() {
+    setPositionAndBroker(-1, null);
+    super.onDetachedFromWindow();
+  }
 
-    public MtpImageView getImageView() {
-        return mImageView;
-    }
+  public MtpImageView getImageView() {
+    return mImageView;
+  }
 
-    public int getPosition() {
-        return mPosition;
-    }
+  public int getPosition() {
+    return mPosition;
+  }
 
-    public void setPositionAndBroker(int position, CheckBroker b) {
-        if (mBroker != null) {
-            mBroker.unregisterOnCheckedChangeListener(this);
-        }
-        mPosition = position;
-        mBroker = b;
-        if (mBroker != null) {
-            setChecked(mBroker.isItemChecked(position));
-            mBroker.registerOnCheckedChangeListener(this);
-        }
+  public void setPositionAndBroker(int position, CheckBroker b) {
+    if (mBroker != null) {
+      mBroker.unregisterOnCheckedChangeListener(this);
     }
+    mPosition = position;
+    mBroker = b;
+    if (mBroker != null) {
+      setChecked(mBroker.isItemChecked(position));
+      mBroker.registerOnCheckedChangeListener(this);
+    }
+  }
 
-    @Override
-    public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
-        if (mBroker != null) mBroker.setItemChecked(mPosition, isChecked);
+  @Override
+  public void onCheckedChanged(CompoundButton arg0, boolean isChecked) {
+    if (mBroker != null) {
+      mBroker.setItemChecked(mPosition, isChecked);
     }
+  }
 
-    @Override
-    public void onCheckedChanged(int position, boolean isChecked) {
-        if (position == mPosition) {
-            setChecked(isChecked);
-        }
+  @Override
+  public void onCheckedChanged(int position, boolean isChecked) {
+    if (position == mPosition) {
+      setChecked(isChecked);
     }
+  }
 
-    @Override
-    public void onBulkCheckedChanged() {
-        if(mBroker != null) setChecked(mBroker.isItemChecked(mPosition));
+  @Override
+  public void onBulkCheckedChanged() {
+    if (mBroker != null) {
+      setChecked(mBroker.isItemChecked(mPosition));
     }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/ui/MtpImageView.java b/src/com/android/gallery3d/ingest/ui/MtpImageView.java
index 80c1051..5362efd 100644
--- a/src/com/android/gallery3d/ingest/ui/MtpImageView.java
+++ b/src/com/android/gallery3d/ingest/ui/MtpImageView.java
@@ -16,12 +16,17 @@
 
 package com.android.gallery3d.ingest.ui;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.BitmapWithMetadata;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
+import com.android.gallery3d.ingest.data.MtpDeviceIndex;
+
 import android.content.Context;
 import android.graphics.Canvas;
 import android.graphics.Matrix;
 import android.graphics.drawable.Drawable;
 import android.mtp.MtpDevice;
-import android.mtp.MtpObjectInfo;
 import android.os.Handler;
 import android.os.HandlerThread;
 import android.os.Looper;
@@ -29,252 +34,264 @@
 import android.util.AttributeSet;
 import android.widget.ImageView;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.MtpDeviceIndex;
-import com.android.gallery3d.ingest.data.BitmapWithMetadata;
-import com.android.gallery3d.ingest.data.MtpBitmapFetch;
-
 import java.lang.ref.WeakReference;
 
+/**
+ * View for images from an MTP devices
+ */
 public class MtpImageView extends ImageView {
-    // We will use the thumbnail for images larger than this threshold
-    private static final int MAX_FULLSIZE_PREVIEW_SIZE = 8388608; // 8 megabytes
+  // We will use the thumbnail for images larger than this threshold
+  private static final int MAX_FULLSIZE_PREVIEW_SIZE = 8388608; // 8 megabytes
 
-    private int mObjectHandle;
-    private int mGeneration;
+  private int mObjectHandle;
+  private int mGeneration;
 
-    private WeakReference<MtpImageView> mWeakReference = new WeakReference<MtpImageView>(this);
-    private Object mFetchLock = new Object();
-    private boolean mFetchPending = false;
-    private MtpObjectInfo mFetchObjectInfo;
-    private MtpDevice mFetchDevice;
-    private Object mFetchResult;
-    private Drawable mOverlayIcon;
-    private boolean mShowOverlayIcon;
+  private WeakReference<MtpImageView> mWeakReference = new WeakReference<MtpImageView>(this);
+  private Object mFetchLock = new Object();
+  private boolean mFetchPending = false;
+  private IngestObjectInfo mFetchObjectInfo;
+  private MtpDevice mFetchDevice;
+  private Object mFetchResult;
+  private Drawable mOverlayIcon;
+  private boolean mShowOverlayIcon;
 
-    private static final FetchImageHandler sFetchHandler = FetchImageHandler.createOnNewThread();
-    private static final ShowImageHandler sFetchCompleteHandler = new ShowImageHandler();
+  private static final FetchImageHandler sFetchHandler = FetchImageHandler.createOnNewThread();
+  private static final ShowImageHandler sFetchCompleteHandler = new ShowImageHandler();
 
-    private void init() {
-         showPlaceholder();
+  private void init() {
+    showPlaceholder();
+  }
+
+  public MtpImageView(Context context) {
+    super(context);
+    init();
+  }
+
+  public MtpImageView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+    init();
+  }
+
+  public MtpImageView(Context context, AttributeSet attrs, int defStyle) {
+    super(context, attrs, defStyle);
+    init();
+  }
+
+  private void showPlaceholder() {
+    setImageResource(android.R.color.transparent);
+  }
+
+  public void setMtpDeviceAndObjectInfo(MtpDevice device, IngestObjectInfo object, int gen) {
+    int handle = object.getObjectHandle();
+    if (handle == mObjectHandle && gen == mGeneration) {
+      return;
+    }
+    cancelLoadingAndClear();
+    showPlaceholder();
+    mGeneration = gen;
+    mObjectHandle = handle;
+    mShowOverlayIcon = MtpDeviceIndex.SUPPORTED_VIDEO_FORMATS.contains(object.getFormat());
+    if (mShowOverlayIcon && mOverlayIcon == null) {
+      mOverlayIcon = getResources().getDrawable(R.drawable.ic_control_play);
+      updateOverlayIconBounds();
+    }
+    synchronized (mFetchLock) {
+      mFetchObjectInfo = object;
+      mFetchDevice = device;
+      if (mFetchPending) {
+        return;
+      }
+      mFetchPending = true;
+      sFetchHandler.sendMessage(
+          sFetchHandler.obtainMessage(0, mWeakReference));
+    }
+  }
+
+  protected Object fetchMtpImageDataFromDevice(MtpDevice device, IngestObjectInfo info) {
+    if (info.getCompressedSize() <= MAX_FULLSIZE_PREVIEW_SIZE
+        && MtpDeviceIndex.SUPPORTED_IMAGE_FORMATS.contains(info.getFormat())) {
+      return MtpBitmapFetch.getFullsize(device, info);
+    } else {
+      return new BitmapWithMetadata(MtpBitmapFetch.getThumbnail(device, info), 0);
+    }
+  }
+
+  private float mLastBitmapWidth;
+  private float mLastBitmapHeight;
+  private int mLastRotationDegrees;
+  private Matrix mDrawMatrix = new Matrix();
+
+  private void updateDrawMatrix() {
+    mDrawMatrix.reset();
+    float dwidth;
+    float dheight;
+    float vheight = getHeight();
+    float vwidth = getWidth();
+    float scale;
+    boolean rotated90 = (mLastRotationDegrees % 180 != 0);
+    if (rotated90) {
+      dwidth = mLastBitmapHeight;
+      dheight = mLastBitmapWidth;
+    } else {
+      dwidth = mLastBitmapWidth;
+      dheight = mLastBitmapHeight;
+    }
+    if (dwidth <= vwidth && dheight <= vheight) {
+      scale = 1.0f;
+    } else {
+      scale = Math.min(vwidth / dwidth, vheight / dheight);
+    }
+    mDrawMatrix.setScale(scale, scale);
+    if (rotated90) {
+      mDrawMatrix.postTranslate(-dheight * scale * 0.5f,
+          -dwidth * scale * 0.5f);
+      mDrawMatrix.postRotate(mLastRotationDegrees);
+      mDrawMatrix.postTranslate(dwidth * scale * 0.5f,
+          dheight * scale * 0.5f);
+    }
+    mDrawMatrix.postTranslate((vwidth - dwidth * scale) * 0.5f,
+        (vheight - dheight * scale) * 0.5f);
+    if (!rotated90 && mLastRotationDegrees > 0) {
+      // rotated by a multiple of 180
+      mDrawMatrix.postRotate(mLastRotationDegrees, vwidth / 2, vheight / 2);
+    }
+    setImageMatrix(mDrawMatrix);
+  }
+
+  private static final int OVERLAY_ICON_SIZE_DENOMINATOR = 4;
+
+  private void updateOverlayIconBounds() {
+    int iheight = mOverlayIcon.getIntrinsicHeight();
+    int iwidth = mOverlayIcon.getIntrinsicWidth();
+    int vheight = getHeight();
+    int vwidth = getWidth();
+    float scaleHeight = ((float) vheight) / (iheight * OVERLAY_ICON_SIZE_DENOMINATOR);
+    float scaleWidth = ((float) vwidth) / (iwidth * OVERLAY_ICON_SIZE_DENOMINATOR);
+    if (scaleHeight >= 1f && scaleWidth >= 1f) {
+      mOverlayIcon.setBounds((vwidth - iwidth) / 2,
+          (vheight - iheight) / 2,
+          (vwidth + iwidth) / 2,
+          (vheight + iheight) / 2);
+    } else {
+      float scale = Math.min(scaleHeight, scaleWidth);
+      mOverlayIcon.setBounds((int) (vwidth - scale * iwidth) / 2,
+          (int) (vheight - scale * iheight) / 2,
+          (int) (vwidth + scale * iwidth) / 2,
+          (int) (vheight + scale * iheight) / 2);
+    }
+  }
+
+  @Override
+  protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
+    super.onLayout(changed, left, top, right, bottom);
+    if (changed && getScaleType() == ScaleType.MATRIX) {
+      updateDrawMatrix();
+    }
+    if (mShowOverlayIcon && changed && mOverlayIcon != null) {
+      updateOverlayIconBounds();
+    }
+  }
+
+  @Override
+  protected void onDraw(Canvas canvas) {
+    super.onDraw(canvas);
+    if (mShowOverlayIcon && mOverlayIcon != null) {
+      mOverlayIcon.draw(canvas);
+    }
+  }
+
+  protected void onMtpImageDataFetchedFromDevice(Object result) {
+    BitmapWithMetadata bitmapWithMetadata = (BitmapWithMetadata) result;
+    if (getScaleType() == ScaleType.MATRIX) {
+      mLastBitmapHeight = bitmapWithMetadata.bitmap.getHeight();
+      mLastBitmapWidth = bitmapWithMetadata.bitmap.getWidth();
+      mLastRotationDegrees = bitmapWithMetadata.rotationDegrees;
+      updateDrawMatrix();
+    } else {
+      setRotation(bitmapWithMetadata.rotationDegrees);
+    }
+    setAlpha(0f);
+    setImageBitmap(bitmapWithMetadata.bitmap);
+    animate().alpha(1f);
+  }
+
+  protected void cancelLoadingAndClear() {
+    synchronized (mFetchLock) {
+      mFetchDevice = null;
+      mFetchObjectInfo = null;
+      mFetchResult = null;
+    }
+    animate().cancel();
+    setImageResource(android.R.color.transparent);
+  }
+
+  @Override
+  public void onDetachedFromWindow() {
+    cancelLoadingAndClear();
+    super.onDetachedFromWindow();
+  }
+
+  private static class FetchImageHandler extends Handler {
+    public FetchImageHandler(Looper l) {
+      super(l);
     }
 
-    public MtpImageView(Context context) {
-        super(context);
-        init();
-    }
-
-    public MtpImageView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
-
-    public MtpImageView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        init();
-    }
-
-    private void showPlaceholder() {
-        setImageResource(android.R.color.transparent);
-    }
-
-    public void setMtpDeviceAndObjectInfo(MtpDevice device, MtpObjectInfo object, int gen) {
-        int handle = object.getObjectHandle();
-        if (handle == mObjectHandle && gen == mGeneration) {
-            return;
-        }
-        cancelLoadingAndClear();
-        showPlaceholder();
-        mGeneration = gen;
-        mObjectHandle = handle;
-        mShowOverlayIcon = MtpDeviceIndex.SUPPORTED_VIDEO_FORMATS.contains(object.getFormat());
-        if (mShowOverlayIcon && mOverlayIcon == null) {
-            mOverlayIcon = getResources().getDrawable(R.drawable.ic_control_play);
-            updateOverlayIconBounds();
-        }
-        synchronized (mFetchLock) {
-            mFetchObjectInfo = object;
-            mFetchDevice = device;
-            if (mFetchPending) return;
-            mFetchPending = true;
-            sFetchHandler.sendMessage(
-                    sFetchHandler.obtainMessage(0, mWeakReference));
-        }
-    }
-
-    protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
-        if (info.getCompressedSize() <= MAX_FULLSIZE_PREVIEW_SIZE
-                && MtpDeviceIndex.SUPPORTED_IMAGE_FORMATS.contains(info.getFormat())) {
-            return MtpBitmapFetch.getFullsize(device, info);
-        } else {
-            return new BitmapWithMetadata(MtpBitmapFetch.getThumbnail(device, info), 0);
-        }
-    }
-
-    private float mLastBitmapWidth;
-    private float mLastBitmapHeight;
-    private int mLastRotationDegrees;
-    private Matrix mDrawMatrix = new Matrix();
-
-    private void updateDrawMatrix() {
-        mDrawMatrix.reset();
-        float dwidth;
-        float dheight;
-        float vheight = getHeight();
-        float vwidth = getWidth();
-        float scale;
-        boolean rotated90 = (mLastRotationDegrees % 180 != 0);
-        if (rotated90) {
-            dwidth = mLastBitmapHeight;
-            dheight = mLastBitmapWidth;
-        } else {
-            dwidth = mLastBitmapWidth;
-            dheight = mLastBitmapHeight;
-        }
-        if (dwidth <= vwidth && dheight <= vheight) {
-            scale = 1.0f;
-        } else {
-            scale = Math.min(vwidth / dwidth, vheight / dheight);
-        }
-        mDrawMatrix.setScale(scale, scale);
-        if (rotated90) {
-            mDrawMatrix.postTranslate(-dheight * scale * 0.5f,
-                    -dwidth * scale * 0.5f);
-            mDrawMatrix.postRotate(mLastRotationDegrees);
-            mDrawMatrix.postTranslate(dwidth * scale * 0.5f,
-                    dheight * scale * 0.5f);
-        }
-        mDrawMatrix.postTranslate((vwidth - dwidth * scale) * 0.5f,
-                (vheight - dheight * scale) * 0.5f);
-        if (!rotated90 && mLastRotationDegrees > 0) {
-            // rotated by a multiple of 180
-            mDrawMatrix.postRotate(mLastRotationDegrees, vwidth / 2, vheight / 2);
-        }
-        setImageMatrix(mDrawMatrix);
-    }
-
-    private static final int OVERLAY_ICON_SIZE_DENOMINATOR = 4;
-
-    private void updateOverlayIconBounds() {
-        int iheight = mOverlayIcon.getIntrinsicHeight();
-        int iwidth = mOverlayIcon.getIntrinsicWidth();
-        int vheight = getHeight();
-        int vwidth = getWidth();
-        float scale_height = ((float) vheight) / (iheight * OVERLAY_ICON_SIZE_DENOMINATOR);
-        float scale_width = ((float) vwidth) / (iwidth * OVERLAY_ICON_SIZE_DENOMINATOR);
-        if (scale_height >= 1f && scale_width >= 1f) {
-            mOverlayIcon.setBounds((vwidth - iwidth) / 2,
-                    (vheight - iheight) / 2,
-                    (vwidth + iwidth) / 2,
-                    (vheight + iheight) / 2);
-        } else {
-            float scale = Math.min(scale_height, scale_width);
-            mOverlayIcon.setBounds((int) (vwidth - scale * iwidth) / 2,
-                    (int) (vheight - scale * iheight) / 2,
-                    (int) (vwidth + scale * iwidth) / 2,
-                    (int) (vheight + scale * iheight) / 2);
-        }
+    public static FetchImageHandler createOnNewThread() {
+      HandlerThread t = new HandlerThread("MtpImageView Fetch");
+      t.start();
+      return new FetchImageHandler(t.getLooper());
     }
 
     @Override
-    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
-        super.onLayout(changed, left, top, right, bottom);
-        if (changed && getScaleType() == ScaleType.MATRIX) {
-            updateDrawMatrix();
+    public void handleMessage(Message msg) {
+      @SuppressWarnings("unchecked")
+      MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
+      if (parent == null) {
+        return;
+      }
+      IngestObjectInfo objectInfo;
+      MtpDevice device;
+      synchronized (parent.mFetchLock) {
+        parent.mFetchPending = false;
+        device = parent.mFetchDevice;
+        objectInfo = parent.mFetchObjectInfo;
+      }
+      if (device == null) {
+        return;
+      }
+      Object result = parent.fetchMtpImageDataFromDevice(device, objectInfo);
+      if (result == null) {
+        return;
+      }
+      synchronized (parent.mFetchLock) {
+        if (parent.mFetchObjectInfo != objectInfo) {
+          return;
         }
-        if (mShowOverlayIcon && changed && mOverlayIcon != null) {
-            updateOverlayIconBounds();
-        }
+        parent.mFetchResult = result;
+        parent.mFetchDevice = null;
+        parent.mFetchObjectInfo = null;
+        sFetchCompleteHandler.sendMessage(
+            sFetchCompleteHandler.obtainMessage(0, parent.mWeakReference));
+      }
     }
+  }
 
+  private static class ShowImageHandler extends Handler {
     @Override
-    protected void onDraw(Canvas canvas) {
-        super.onDraw(canvas);
-        if (mShowOverlayIcon && mOverlayIcon != null) {
-            mOverlayIcon.draw(canvas);
-        }
+    public void handleMessage(Message msg) {
+      @SuppressWarnings("unchecked")
+      MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
+      if (parent == null) {
+        return;
+      }
+      Object result;
+      synchronized (parent.mFetchLock) {
+        result = parent.mFetchResult;
+      }
+      if (result == null) {
+        return;
+      }
+      parent.onMtpImageDataFetchedFromDevice(result);
     }
-
-    protected void onMtpImageDataFetchedFromDevice(Object result) {
-        BitmapWithMetadata bitmapWithMetadata = (BitmapWithMetadata)result;
-        if (getScaleType() == ScaleType.MATRIX) {
-            mLastBitmapHeight = bitmapWithMetadata.bitmap.getHeight();
-            mLastBitmapWidth = bitmapWithMetadata.bitmap.getWidth();
-            mLastRotationDegrees = bitmapWithMetadata.rotationDegrees;
-            updateDrawMatrix();
-        } else {
-            setRotation(bitmapWithMetadata.rotationDegrees);
-        }
-        setAlpha(0f);
-        setImageBitmap(bitmapWithMetadata.bitmap);
-        animate().alpha(1f);
-    }
-
-    protected void cancelLoadingAndClear() {
-        synchronized (mFetchLock) {
-            mFetchDevice = null;
-            mFetchObjectInfo = null;
-            mFetchResult = null;
-        }
-        animate().cancel();
-        setImageResource(android.R.color.transparent);
-    }
-
-    @Override
-    public void onDetachedFromWindow() {
-        cancelLoadingAndClear();
-        super.onDetachedFromWindow();
-    }
-
-    private static class FetchImageHandler extends Handler {
-        public FetchImageHandler(Looper l) {
-            super(l);
-        }
-
-        public static FetchImageHandler createOnNewThread() {
-            HandlerThread t = new HandlerThread("MtpImageView Fetch");
-            t.start();
-            return new FetchImageHandler(t.getLooper());
-        }
-
-        @Override
-        public void handleMessage(Message msg) {
-            @SuppressWarnings("unchecked")
-            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
-            if (parent == null) return;
-            MtpObjectInfo objectInfo;
-            MtpDevice device;
-            synchronized (parent.mFetchLock) {
-                parent.mFetchPending = false;
-                device = parent.mFetchDevice;
-                objectInfo = parent.mFetchObjectInfo;
-            }
-            if (device == null) return;
-            Object result = parent.fetchMtpImageDataFromDevice(device, objectInfo);
-            if (result == null) return;
-            synchronized (parent.mFetchLock) {
-                if (parent.mFetchObjectInfo != objectInfo) return;
-                parent.mFetchResult = result;
-                parent.mFetchDevice = null;
-                parent.mFetchObjectInfo = null;
-                sFetchCompleteHandler.sendMessage(
-                        sFetchCompleteHandler.obtainMessage(0, parent.mWeakReference));
-            }
-        }
-    }
-
-    private static class ShowImageHandler extends Handler {
-        @Override
-        public void handleMessage(Message msg) {
-            @SuppressWarnings("unchecked")
-            MtpImageView parent = ((WeakReference<MtpImageView>) msg.obj).get();
-            if (parent == null) return;
-            Object result;
-            synchronized (parent.mFetchLock) {
-                result = parent.mFetchResult;
-            }
-            if (result == null) return;
-            parent.onMtpImageDataFetchedFromDevice(result);
-        }
-    }
+  }
 }
diff --git a/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java b/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
index 3307e78..844a750 100644
--- a/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
+++ b/src/com/android/gallery3d/ingest/ui/MtpThumbnailTileView.java
@@ -16,91 +16,98 @@
 
 package com.android.gallery3d.ingest.ui;
 
+import com.android.gallery3d.R;
+import com.android.gallery3d.ingest.data.IngestObjectInfo;
+import com.android.gallery3d.ingest.data.MtpBitmapFetch;
+
 import android.content.Context;
 import android.graphics.Bitmap;
 import android.graphics.Canvas;
 import android.graphics.Paint;
 import android.mtp.MtpDevice;
-import android.mtp.MtpObjectInfo;
 import android.util.AttributeSet;
 import android.widget.Checkable;
 
-import com.android.gallery3d.R;
-import com.android.gallery3d.ingest.data.MtpBitmapFetch;
 
-
+/**
+ * View for thumbnail images from an MTP device
+ */
 public class MtpThumbnailTileView extends MtpImageView implements Checkable {
 
-    private Paint mForegroundPaint;
-    private boolean mIsChecked;
-    private Bitmap mBitmap;
+  private Paint mForegroundPaint;
+  private boolean mIsChecked;
+  private Bitmap mBitmap;
 
-    private void init() {
-        mForegroundPaint = new Paint();
-        mForegroundPaint.setColor(getResources().getColor(R.color.ingest_highlight_semitransparent));
-    }
+  private void init() {
+    mForegroundPaint = new Paint();
+    mForegroundPaint.setColor(
+        getResources().getColor(R.color.ingest_highlight_semitransparent));
+  }
 
-    public MtpThumbnailTileView(Context context) {
-        super(context);
-        init();
-    }
+  public MtpThumbnailTileView(Context context) {
+    super(context);
+    init();
+  }
 
-    public MtpThumbnailTileView(Context context, AttributeSet attrs) {
-        super(context, attrs);
-        init();
-    }
+  public MtpThumbnailTileView(Context context, AttributeSet attrs) {
+    super(context, attrs);
+    init();
+  }
 
-    public MtpThumbnailTileView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        init();
-    }
+  public MtpThumbnailTileView(Context context, AttributeSet attrs, int defStyle) {
+    super(context, attrs, defStyle);
+    init();
+  }
 
-    @Override
-    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        // Force this to be square
-        super.onMeasure(widthMeasureSpec, widthMeasureSpec);
-    }
+  @Override
+  public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+    // Force this to be square
+    super.onMeasure(widthMeasureSpec, widthMeasureSpec);
+  }
 
-    @Override
-    protected Object fetchMtpImageDataFromDevice(MtpDevice device, MtpObjectInfo info) {
-        return MtpBitmapFetch.getThumbnail(device, info);
-    }
+  @Override
+  protected Object fetchMtpImageDataFromDevice(MtpDevice device, IngestObjectInfo info) {
+    return MtpBitmapFetch.getThumbnail(device, info);
+  }
 
-    @Override
-    protected void onMtpImageDataFetchedFromDevice(Object result) {
-        mBitmap = (Bitmap)result;
-        setImageBitmap(mBitmap);
-    }
+  @Override
+  protected void onMtpImageDataFetchedFromDevice(Object result) {
+    mBitmap = (Bitmap) result;
+    setImageBitmap(mBitmap);
+  }
 
-    @Override
-    public void draw(Canvas canvas) {
-        super.draw(canvas);
-        if (isChecked()) {
-            canvas.drawRect(canvas.getClipBounds(), mForegroundPaint);
-        }
+  @Override
+  public void draw(Canvas canvas) {
+    super.draw(canvas);
+    if (isChecked()) {
+      canvas.drawRect(canvas.getClipBounds(), mForegroundPaint);
     }
+  }
 
-    @Override
-    public boolean isChecked() {
-        return mIsChecked;
-    }
+  @Override
+  public boolean isChecked() {
+    return mIsChecked;
+  }
 
-    @Override
-    public void setChecked(boolean checked) {
-        mIsChecked = checked;
+  @Override
+  public void setChecked(boolean checked) {
+    if (mIsChecked != checked) {
+      mIsChecked = checked;
+      invalidate();
     }
+  }
 
-    @Override
-    public void toggle() {
-        setChecked(!mIsChecked);
-    }
+  @Override
+  public void toggle() {
+    setChecked(!mIsChecked);
+  }
 
-    @Override
-    protected void cancelLoadingAndClear() {
-        super.cancelLoadingAndClear();
-        if (mBitmap != null) {
-            MtpBitmapFetch.recycleThumbnail(mBitmap);
-            mBitmap = null;
-        }
+  @Override
+  protected void cancelLoadingAndClear() {
+    super.cancelLoadingAndClear();
+    if (mBitmap != null) {
+      MtpBitmapFetch.recycleThumbnail(mBitmap);
+      mBitmap = null;
     }
+  }
 }
