diff --git a/src/com/android/documentsui/BaseActivity.java b/src/com/android/documentsui/BaseActivity.java
index 9f5e66c..d9d6cf4 100644
--- a/src/com/android/documentsui/BaseActivity.java
+++ b/src/com/android/documentsui/BaseActivity.java
@@ -47,7 +47,6 @@
 import android.support.v7.widget.RecyclerView;
 import android.util.Log;
 import android.view.KeyEvent;
-import android.view.KeyboardShortcutGroup;
 import android.view.Menu;
 import android.view.MenuItem;
 import android.view.View;
diff --git a/src/com/android/documentsui/DirectoryLoader.java b/src/com/android/documentsui/DirectoryLoader.java
index ab79d01..d2c7d10 100644
--- a/src/com/android/documentsui/DirectoryLoader.java
+++ b/src/com/android/documentsui/DirectoryLoader.java
@@ -25,7 +25,6 @@
 import android.os.CancellationSignal;
 import android.os.OperationCanceledException;
 import android.os.RemoteException;
-import android.provider.DocumentsContract;
 import android.provider.DocumentsContract.Document;
 import android.util.Log;
 
@@ -35,8 +34,6 @@
 import com.android.documentsui.roots.RootCursorWrapper;
 import com.android.documentsui.sorting.SortModel;
 
-import java.io.FileNotFoundException;
-
 import libcore.io.IoUtils;
 
 public class DirectoryLoader extends AsyncTaskLoader<DirectoryResult> {
@@ -86,7 +83,6 @@
 
         final DirectoryResult result = new DirectoryResult();
         result.doc = mDoc;
-        result.sortModel = mModel;
 
         ContentProviderClient client = null;
         Cursor cursor;
@@ -107,6 +103,8 @@
                 cursor = new FilteringCursorWrapper(cursor, null, SEARCH_REJECT_MIMES);
             }
 
+            cursor = mModel.sortCursor(cursor);
+
             result.client = client;
             result.cursor = cursor;
         } catch (Exception e) {
diff --git a/src/com/android/documentsui/DirectoryResult.java b/src/com/android/documentsui/DirectoryResult.java
index 32910ce..9e4d9f3 100644
--- a/src/com/android/documentsui/DirectoryResult.java
+++ b/src/com/android/documentsui/DirectoryResult.java
@@ -20,7 +20,6 @@
 import android.database.Cursor;
 
 import com.android.documentsui.base.DocumentInfo;
-import com.android.documentsui.sorting.SortModel;
 
 import libcore.io.IoUtils;
 
@@ -29,7 +28,6 @@
     public Cursor cursor;
     public Exception exception;
     public DocumentInfo doc;
-    public SortModel sortModel;
 
     @Override
     public void close() {
@@ -37,6 +35,6 @@
         ContentProviderClient.releaseQuietly(client);
         cursor = null;
         client = null;
-        sortModel = null;
+        doc = null;
     }
 }
diff --git a/src/com/android/documentsui/RecentsLoader.java b/src/com/android/documentsui/RecentsLoader.java
index dc4d9f2..6ce1896 100644
--- a/src/com/android/documentsui/RecentsLoader.java
+++ b/src/com/android/documentsui/RecentsLoader.java
@@ -40,10 +40,10 @@
 import com.android.documentsui.roots.RootsAccess;
 import com.android.internal.annotations.GuardedBy;
 
-import com.google.common.util.concurrent.AbstractFuture;
-
 import libcore.io.IoUtils;
 
+import com.google.common.util.concurrent.AbstractFuture;
+
 import java.io.Closeable;
 import java.io.IOException;
 import java.util.ArrayList;
@@ -180,7 +180,6 @@
         }
 
         final DirectoryResult result = new DirectoryResult();
-        result.sortModel = mState.sortModel;
 
         final Cursor merged;
         if (cursors.size() > 0) {
@@ -190,13 +189,16 @@
             merged = new MatrixCursor(new String[0]);
         }
 
+
+        final Cursor sorted = mState.sortModel.sortCursor(merged);
+
         // Tell the UI if this is an in-progress result. When loading is complete, another update is
         // sent with EXTRA_LOADING set to false.
         Bundle extras = new Bundle();
         extras.putBoolean(DocumentsContract.EXTRA_LOADING, !allDone);
-        merged.setExtras(extras);
+        sorted.setExtras(extras);
 
-        result.cursor = merged;
+        result.cursor = sorted;
 
         return result;
     }
diff --git a/src/com/android/documentsui/dirlist/Model.java b/src/com/android/documentsui/dirlist/Model.java
index 7973101..6c08859 100644
--- a/src/com/android/documentsui/dirlist/Model.java
+++ b/src/com/android/documentsui/dirlist/Model.java
@@ -16,7 +16,6 @@
 
 package com.android.documentsui.dirlist;
 
-import static com.android.documentsui.base.DocumentInfo.getCursorLong;
 import static com.android.documentsui.base.DocumentInfo.getCursorString;
 import static com.android.documentsui.base.Shared.DEBUG;
 
@@ -34,11 +33,8 @@
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.base.DocumentInfo;
 import com.android.documentsui.base.EventListener;
-import com.android.documentsui.base.Shared;
 import com.android.documentsui.dirlist.MultiSelectManager.Selection;
 import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.sorting.SortDimension;
-import com.android.documentsui.sorting.SortModel;
 
 import java.lang.annotation.Retention;
 import java.lang.annotation.RetentionPolicy;
@@ -60,12 +56,7 @@
     private int mCursorCount;
     /** Maps Model ID to cursor positions, for looking up items by Model ID. */
     private Map<String, Integer> mPositions = new HashMap<>();
-    /**
-     * A sorted array of model IDs for the files currently in the Model.  Sort order is determined
-     * by {@link #mSortModel}
-     */
     private String mIds[] = new String[0];
-    private SortModel mSortModel;
 
     @Nullable String info;
     @Nullable String error;
@@ -126,7 +117,6 @@
 
         mCursor = result.cursor;
         mCursorCount = mCursor.getCount();
-        mSortModel = result.sortModel;
         doc = result.doc;
 
         updateModelData();
@@ -151,24 +141,7 @@
      * according to the current sort order.
      */
     private void updateModelData() {
-        int[] positions = new int[mCursorCount];
         mIds = new String[mCursorCount];
-        boolean[] isDirs = new boolean[mCursorCount];
-        String[] displayNames = null;
-        long[] longValues = null;
-
-        final int id = mSortModel.getSortedDimensionId();
-        switch (id) {
-            case SortModel.SORT_DIMENSION_ID_TITLE:
-                displayNames = new String[mCursorCount];
-                break;
-            case SortModel.SORT_DIMENSION_ID_DATE:
-            case SortModel.SORT_DIMENSION_ID_SIZE:
-                longValues = new long[mCursorCount];
-                break;
-        }
-
-        String mimeType;
 
         mCursor.moveToPosition(-1);
         for (int pos = 0; pos < mCursorCount; ++pos) {
@@ -176,246 +149,25 @@
                 Log.e(TAG, "Fail to move cursor to next pos: " + pos);
                 return;
             }
-            positions[pos] = pos;
-
             // Generates a Model ID for a cursor entry that refers to a document. The Model ID is a
             // unique string that can be used to identify the document referred to by the cursor.
             // If the cursor is a merged cursor over multiple authorities, then prefix the ids
             // with the authority to avoid collisions.
             if (mCursor instanceof MergeCursor) {
-                mIds[pos] = getCursorString(mCursor, RootCursorWrapper.COLUMN_AUTHORITY) + "|" +
-                        getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
+                mIds[pos] = getCursorString(mCursor, RootCursorWrapper.COLUMN_AUTHORITY)
+                        + "|" + getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
             } else {
                 mIds[pos] = getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
             }
-
-            mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
-            isDirs[pos] = Document.MIME_TYPE_DIR.equals(mimeType);
-
-            switch(id) {
-                case SortModel.SORT_DIMENSION_ID_TITLE:
-                    final String displayName = getCursorString(
-                            mCursor, Document.COLUMN_DISPLAY_NAME);
-                    displayNames[pos] = displayName;
-                    break;
-                case SortModel.SORT_DIMENSION_ID_DATE:
-                    longValues[pos] = getLastModified(mCursor);
-                    break;
-                case SortModel.SORT_DIMENSION_ID_SIZE:
-                    longValues[pos] = getCursorLong(mCursor, Document.COLUMN_SIZE);
-                    break;
-            }
-        }
-
-        final SortDimension dimension = mSortModel.getDimensionById(id);
-        switch (id) {
-            case SortModel.SORT_DIMENSION_ID_TITLE:
-                binarySort(displayNames, isDirs, positions, mIds, dimension.getSortDirection());
-                break;
-            case SortModel.SORT_DIMENSION_ID_DATE:
-            case SortModel.SORT_DIMENSION_ID_SIZE:
-                binarySort(longValues, isDirs, positions, mIds, dimension.getSortDirection());
-                break;
         }
 
         // Populate the positions.
         mPositions.clear();
         for (int i = 0; i < mCursorCount; ++i) {
-            mPositions.put(mIds[i], positions[i]);
+            mPositions.put(mIds[i], i);
         }
     }
 
-    /**
-     * Sorts model data. Takes three columns of index-corresponded data. The first column is the
-     * sort key. Rows are sorted in ascending alphabetical order on the sort key.
-     * Directories are always shown first. This code is based on TimSort.binarySort().
-     *
-     * @param sortKey Data is sorted in ascending alphabetical order.
-     * @param isDirs Array saying whether an item is a directory or not.
-     * @param positions Cursor positions to be sorted.
-     * @param ids Model IDs to be sorted.
-     */
-    private static void binarySort(
-            String[] sortKey,
-            boolean[] isDirs,
-            int[] positions,
-            String[] ids,
-            @SortDimension.SortDirection int direction) {
-        final int count = positions.length;
-        for (int start = 1; start < count; start++) {
-            final int pivotPosition = positions[start];
-            final String pivotValue = sortKey[start];
-            final boolean pivotIsDir = isDirs[start];
-            final String pivotId = ids[start];
-
-            int left = 0;
-            int right = start;
-
-            while (left < right) {
-                int mid = (left + right) >>> 1;
-
-                // Directories always go in front.
-                int compare = 0;
-                final boolean rhsIsDir = isDirs[mid];
-                if (pivotIsDir && !rhsIsDir) {
-                    compare = -1;
-                } else if (!pivotIsDir && rhsIsDir) {
-                    compare = 1;
-                } else {
-                    final String lhs = pivotValue;
-                    final String rhs = sortKey[mid];
-                    switch (direction) {
-                        case SortDimension.SORT_DIRECTION_ASCENDING:
-                            compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
-                            break;
-                        case SortDimension.SORT_DIRECTION_DESCENDING:
-                            compare = -Shared.compareToIgnoreCaseNullable(lhs, rhs);
-                            break;
-                        default:
-                            throw new IllegalArgumentException(
-                                    "Unknown sorting direction: " + direction);
-                    }
-                }
-
-                if (compare < 0) {
-                    right = mid;
-                } else {
-                    left = mid + 1;
-                }
-            }
-
-            int n = start - left;
-            switch (n) {
-                case 2:
-                    positions[left + 2] = positions[left + 1];
-                    sortKey[left + 2] = sortKey[left + 1];
-                    isDirs[left + 2] = isDirs[left + 1];
-                    ids[left + 2] = ids[left + 1];
-                case 1:
-                    positions[left + 1] = positions[left];
-                    sortKey[left + 1] = sortKey[left];
-                    isDirs[left + 1] = isDirs[left];
-                    ids[left + 1] = ids[left];
-                    break;
-                default:
-                    System.arraycopy(positions, left, positions, left + 1, n);
-                    System.arraycopy(sortKey, left, sortKey, left + 1, n);
-                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
-                    System.arraycopy(ids, left, ids, left + 1, n);
-            }
-
-            positions[left] = pivotPosition;
-            sortKey[left] = pivotValue;
-            isDirs[left] = pivotIsDir;
-            ids[left] = pivotId;
-        }
-    }
-
-    /**
-     * Sorts model data. Takes four columns of index-corresponded data. The first column is the sort
-     * key, and the second is an array of mime types. The rows are first bucketed by mime type
-     * (directories vs documents) and then each bucket is sorted independently in descending
-     * numerical order on the sort key. This code is based on TimSort.binarySort().
-     *
-     * @param sortKey Data is sorted in descending numerical order.
-     * @param isDirs Array saying whether an item is a directory or not.
-     * @param positions Cursor positions to be sorted.
-     * @param ids Model IDs to be sorted.
-     */
-    private static void binarySort(
-            long[] sortKey,
-            boolean[] isDirs,
-            int[] positions,
-            String[] ids,
-            @SortDimension.SortDirection int direction) {
-        final int count = positions.length;
-        for (int start = 1; start < count; start++) {
-            final int pivotPosition = positions[start];
-            final long pivotValue = sortKey[start];
-            final boolean pivotIsDir = isDirs[start];
-            final String pivotId = ids[start];
-
-            int left = 0;
-            int right = start;
-
-            while (left < right) {
-                int mid = ((left + right) >>> 1);
-
-                // Directories always go in front.
-                int compare = 0;
-                final boolean rhsIsDir = isDirs[mid];
-                if (pivotIsDir && !rhsIsDir) {
-                    compare = -1;
-                } else if (!pivotIsDir && rhsIsDir) {
-                    compare = 1;
-                } else {
-                    final long lhs = pivotValue;
-                    final long rhs = sortKey[mid];
-                    switch (direction) {
-                        case SortDimension.SORT_DIRECTION_ASCENDING:
-                            compare = Long.compare(lhs, rhs);
-                            break;
-                        case SortDimension.SORT_DIRECTION_DESCENDING:
-                            compare = -Long.compare(lhs, rhs);
-                            break;
-                        default:
-                            throw new IllegalArgumentException(
-                                    "Unknown sorting direction: " + direction);
-                    }
-                }
-
-                // If numerical comparison yields a tie, use document ID as a tie breaker.  This
-                // will yield stable results even if incoming items are continually shuffling and
-                // have identical numerical sort keys.  One common example of this scenario is seen
-                // when sorting a set of active downloads by mod time.
-                if (compare == 0) {
-                    compare = pivotId.compareTo(ids[mid]);
-                }
-
-                if (compare < 0) {
-                    right = mid;
-                } else {
-                    left = mid + 1;
-                }
-            }
-
-            int n = start - left;
-            switch (n) {
-                case 2:
-                    positions[left + 2] = positions[left + 1];
-                    sortKey[left + 2] = sortKey[left + 1];
-                    isDirs[left + 2] = isDirs[left + 1];
-                    ids[left + 2] = ids[left + 1];
-                case 1:
-                    positions[left + 1] = positions[left];
-                    sortKey[left + 1] = sortKey[left];
-                    isDirs[left + 1] = isDirs[left];
-                    ids[left + 1] = ids[left];
-                    break;
-                default:
-                    System.arraycopy(positions, left, positions, left + 1, n);
-                    System.arraycopy(sortKey, left, sortKey, left + 1, n);
-                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
-                    System.arraycopy(ids, left, ids, left + 1, n);
-            }
-
-            positions[left] = pivotPosition;
-            sortKey[left] = pivotValue;
-            isDirs[left] = pivotIsDir;
-            ids[left] = pivotId;
-        }
-    }
-
-    /**
-     * @return Timestamp for the given document. Some docs (e.g. active downloads) have a null
-     * timestamp - these will be replaced with MAX_LONG so that such files get sorted to the top
-     * when sorting descending by date.
-     */
-    long getLastModified(Cursor cursor) {
-        long l = getCursorLong(mCursor, Document.COLUMN_LAST_MODIFIED);
-        return (l == -1) ? Long.MAX_VALUE : l;
-    }
-
     public @Nullable Cursor getItem(String modelId) {
         Integer pos = mPositions.get(modelId);
         if (pos == null) {
diff --git a/src/com/android/documentsui/sorting/SortModel.java b/src/com/android/documentsui/sorting/SortModel.java
index 793dd60..f64bc28 100644
--- a/src/com/android/documentsui/sorting/SortModel.java
+++ b/src/com/android/documentsui/sorting/SortModel.java
@@ -20,6 +20,7 @@
 
 import android.annotation.IntDef;
 import android.annotation.Nullable;
+import android.database.Cursor;
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.provider.DocumentsContract.Document;
@@ -239,6 +240,14 @@
         notifyListeners(UPDATE_TYPE_VISIBILITY);
     }
 
+    public Cursor sortCursor(Cursor cursor) {
+        if (mSortedDimension != null) {
+            return new SortingCursorWrapper(cursor, mSortedDimension);
+        } else {
+            return cursor;
+        }
+    }
+
     public @Nullable String getDocumentSortQuery() {
         final int id = getSortedDimensionId();
         final String columnName;
diff --git a/src/com/android/documentsui/sorting/SortingCursorWrapper.java b/src/com/android/documentsui/sorting/SortingCursorWrapper.java
new file mode 100644
index 0000000..89869d9
--- /dev/null
+++ b/src/com/android/documentsui/sorting/SortingCursorWrapper.java
@@ -0,0 +1,330 @@
+/*
+ * Copyright (C) 2016 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.documentsui.sorting;
+
+import static com.android.documentsui.base.DocumentInfo.getCursorLong;
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.provider.DocumentsContract.Document;
+
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.sorting.SortModel.SortDimensionId;
+
+/**
+ * Cursor wrapper that presents a sorted view of the underlying cursor. Handles
+ * common {@link Document} sorting modes, such as ordering directories first.
+ */
+class SortingCursorWrapper extends AbstractCursor {
+    private final Cursor mCursor;
+
+    private final int[] mPosition;
+
+    public SortingCursorWrapper(Cursor cursor, SortDimension dimension) {
+        mCursor = cursor;
+
+        final int count = cursor.getCount();
+        mPosition = new int[count];
+        boolean[] isDirs = new boolean[count];
+        String[] displayNames = null;
+        long[] longValues = null;
+        String[] ids = null;
+
+        final @SortDimensionId int id = dimension.getId();
+        switch (id) {
+            case SortModel.SORT_DIMENSION_ID_TITLE:
+                displayNames = new String[count];
+                break;
+            case SortModel.SORT_DIMENSION_ID_DATE:
+            case SortModel.SORT_DIMENSION_ID_SIZE:
+                longValues = new long[count];
+                ids = new String[count];
+                break;
+        }
+
+        cursor.moveToPosition(-1);
+        for (int i = 0; i < count; i++) {
+            cursor.moveToNext();
+            mPosition[i] = i;
+
+            final String mimeType = getCursorString(mCursor, Document.COLUMN_MIME_TYPE);
+            isDirs[i] = Document.MIME_TYPE_DIR.equals(mimeType);
+
+            switch(id) {
+                case SortModel.SORT_DIMENSION_ID_TITLE:
+                    final String displayName = getCursorString(
+                            mCursor, Document.COLUMN_DISPLAY_NAME);
+                    displayNames[i] = displayName;
+                    break;
+                case SortModel.SORT_DIMENSION_ID_DATE:
+                    longValues[i] = getLastModified(mCursor);
+                    ids[i] = getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
+                    break;
+                case SortModel.SORT_DIMENSION_ID_SIZE:
+                    longValues[i] = getCursorLong(mCursor, Document.COLUMN_SIZE);
+                    ids[i] = getCursorString(mCursor, Document.COLUMN_DOCUMENT_ID);
+                    break;
+            }
+
+        }
+
+        switch (id) {
+            case SortModel.SORT_DIMENSION_ID_TITLE:
+                binarySort(displayNames, isDirs, mPosition, dimension.getSortDirection());
+                break;
+            case SortModel.SORT_DIMENSION_ID_DATE:
+            case SortModel.SORT_DIMENSION_ID_SIZE:
+                binarySort(longValues, isDirs, mPosition, ids, dimension.getSortDirection());
+                break;
+        }
+
+    }
+
+    @Override
+    public void close() {
+        super.close();
+        mCursor.close();
+    }
+
+    @Override
+    public boolean onMove(int oldPosition, int newPosition) {
+        return mCursor.moveToPosition(mPosition[newPosition]);
+    }
+
+    @Override
+    public String[] getColumnNames() {
+        return mCursor.getColumnNames();
+    }
+
+    @Override
+    public int getCount() {
+        return mCursor.getCount();
+    }
+
+    @Override
+    public double getDouble(int column) {
+        return mCursor.getDouble(column);
+    }
+
+    @Override
+    public float getFloat(int column) {
+        return mCursor.getFloat(column);
+    }
+
+    @Override
+    public int getInt(int column) {
+        return mCursor.getInt(column);
+    }
+
+    @Override
+    public long getLong(int column) {
+        return mCursor.getLong(column);
+    }
+
+    @Override
+    public short getShort(int column) {
+        return mCursor.getShort(column);
+    }
+
+    @Override
+    public String getString(int column) {
+        return mCursor.getString(column);
+    }
+
+    @Override
+    public int getType(int column) {
+        return mCursor.getType(column);
+    }
+
+    @Override
+    public boolean isNull(int column) {
+        return mCursor.isNull(column);
+    }
+
+    /**
+     * @return Timestamp for the given document. Some docs (e.g. active downloads) have a null
+     * timestamp - these will be replaced with MAX_LONG so that such files get sorted to the top
+     * when sorting descending by date.
+     */
+    private static long getLastModified(Cursor cursor) {
+        long l = getCursorLong(cursor, Document.COLUMN_LAST_MODIFIED);
+        return (l == -1) ? Long.MAX_VALUE : l;
+    }
+
+    /**
+     * Borrowed from TimSort.binarySort(), but modified to sort two column
+     * dataset.
+     */
+    private static void binarySort(
+            String[] sortKey,
+            boolean[] isDirs,
+            int[] positions,
+            @SortDimension.SortDirection int direction) {
+        final int count = positions.length;
+        for (int start = 1; start < count; start++) {
+            final int pivotPosition = positions[start];
+            final String pivotValue = sortKey[start];
+            final boolean pivotIsDir = isDirs[start];
+
+            int left = 0;
+            int right = start;
+
+            while (left < right) {
+                int mid = (left + right) >>> 1;
+
+                // Directories always go in front.
+                int compare = 0;
+                final boolean rhsIsDir = isDirs[mid];
+                if (pivotIsDir && !rhsIsDir) {
+                    compare = -1;
+                } else if (!pivotIsDir && rhsIsDir) {
+                    compare = 1;
+                } else {
+                    final String lhs = pivotValue;
+                    final String rhs = sortKey[mid];
+                    switch (direction) {
+                        case SortDimension.SORT_DIRECTION_ASCENDING:
+                            compare = Shared.compareToIgnoreCaseNullable(lhs, rhs);
+                            break;
+                        case SortDimension.SORT_DIRECTION_DESCENDING:
+                            compare = -Shared.compareToIgnoreCaseNullable(lhs, rhs);
+                            break;
+                        default:
+                            throw new IllegalArgumentException(
+                                    "Unknown sorting direction: " + direction);
+                    }
+                }
+
+                if (compare < 0) {
+                    right = mid;
+                } else {
+                    left = mid + 1;
+                }
+            }
+
+            int n = start - left;
+            switch (n) {
+                case 2:
+                    positions[left + 2] = positions[left + 1];
+                    sortKey[left + 2] = sortKey[left + 1];
+                    isDirs[left + 2] = isDirs[left + 1];
+                case 1:
+                    positions[left + 1] = positions[left];
+                    sortKey[left + 1] = sortKey[left];
+                    isDirs[left + 1] = isDirs[left];
+                    break;
+                default:
+                    System.arraycopy(positions, left, positions, left + 1, n);
+                    System.arraycopy(sortKey, left, sortKey, left + 1, n);
+                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
+            }
+
+            positions[left] = pivotPosition;
+            sortKey[left] = pivotValue;
+            isDirs[left] = pivotIsDir;
+        }
+    }
+
+    /**
+     * Borrowed from TimSort.binarySort(), but modified to sort two column
+     * dataset.
+     */
+    private static void binarySort(
+            long[] sortKey,
+            boolean[] isDirs,
+            int[] positions,
+            String[] ids,
+            @SortDimension.SortDirection int direction) {
+        final int count = positions.length;
+        for (int start = 1; start < count; start++) {
+            final int pivotPosition = positions[start];
+            final long pivotValue = sortKey[start];
+            final boolean pivotIsDir = isDirs[start];
+            final String pivotId = ids[start];
+
+            int left = 0;
+            int right = start;
+
+            while (left < right) {
+                int mid = ((left + right) >>> 1);
+
+                // Directories always go in front.
+                int compare = 0;
+                final boolean rhsIsDir = isDirs[mid];
+                if (pivotIsDir && !rhsIsDir) {
+                    compare = -1;
+                } else if (!pivotIsDir && rhsIsDir) {
+                    compare = 1;
+                } else {
+                    final long lhs = pivotValue;
+                    final long rhs = sortKey[mid];
+                    switch (direction) {
+                        case SortDimension.SORT_DIRECTION_ASCENDING:
+                            compare = Long.compare(lhs, rhs);
+                            break;
+                        case SortDimension.SORT_DIRECTION_DESCENDING:
+                            compare = -Long.compare(lhs, rhs);
+                            break;
+                        default:
+                            throw new IllegalArgumentException(
+                                    "Unknown sorting direction: " + direction);
+                    }
+                }
+
+                // If numerical comparison yields a tie, use document ID as a tie breaker.  This
+                // will yield stable results even if incoming items are continually shuffling and
+                // have identical numerical sort keys.  One common example of this scenario is seen
+                // when sorting a set of active downloads by mod time.
+                if (compare == 0) {
+                    compare = pivotId.compareTo(ids[mid]);
+                }
+
+                if (compare < 0) {
+                    right = mid;
+                } else {
+                    left = mid + 1;
+                }
+            }
+
+            int n = start - left;
+            switch (n) {
+                case 2:
+                    positions[left + 2] = positions[left + 1];
+                    sortKey[left + 2] = sortKey[left + 1];
+                    isDirs[left + 2] = isDirs[left + 1];
+                    ids[left + 2] = ids[left + 1];
+                case 1:
+                    positions[left + 1] = positions[left];
+                    sortKey[left + 1] = sortKey[left];
+                    isDirs[left + 1] = isDirs[left];
+                    ids[left + 1] = ids[left];
+                    break;
+                default:
+                    System.arraycopy(positions, left, positions, left + 1, n);
+                    System.arraycopy(sortKey, left, sortKey, left + 1, n);
+                    System.arraycopy(isDirs, left, isDirs, left + 1, n);
+                    System.arraycopy(ids, left, ids, left + 1, n);
+            }
+
+            positions[left] = pivotPosition;
+            sortKey[left] = pivotValue;
+            isDirs[left] = pivotIsDir;
+            ids[left] = pivotId;
+        }
+    }
+}
diff --git a/tests/common/com/android/documentsui/dirlist/TestModel.java b/tests/common/com/android/documentsui/dirlist/TestModel.java
index 0c3ca92..1204400 100644
--- a/tests/common/com/android/documentsui/dirlist/TestModel.java
+++ b/tests/common/com/android/documentsui/dirlist/TestModel.java
@@ -21,7 +21,6 @@
 
 import com.android.documentsui.DirectoryResult;
 import com.android.documentsui.roots.RootCursorWrapper;
-import com.android.documentsui.testing.SortModels;
 
 import java.util.Random;
 
@@ -60,7 +59,6 @@
 
         DirectoryResult r = new DirectoryResult();
         r.cursor = c;
-        r.sortModel = SortModels.createTestSortModel();
         update(r);
     }
 
diff --git a/tests/unit/com/android/documentsui/dirlist/ModelTest.java b/tests/unit/com/android/documentsui/dirlist/ModelTest.java
index b9dab0d..faad880 100644
--- a/tests/unit/com/android/documentsui/dirlist/ModelTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/ModelTest.java
@@ -74,7 +74,6 @@
     private Cursor cursor;
     private Model model;
     private TestContentProvider provider;
-    private SortModel sortModel;
 
     @Override
     public void setUp() {
@@ -94,11 +93,9 @@
             row.add(Document.COLUMN_SIZE, rand.nextInt());
         }
         cursor = c;
-        sortModel = SortModels.createTestSortModel();
 
         DirectoryResult r = new DirectoryResult();
         r.cursor = cursor;
-        r.sortModel = sortModel;
 
         // Instantiate the model with a dummy view adapter and listener that (for now) do nothing.
         model = new Model();
@@ -136,7 +133,6 @@
         // Update the model, then make sure it contains all the expected items.
         DirectoryResult r = new DirectoryResult();
         r.cursor = cIn;
-        r.sortModel = SortModels.createTestSortModel();
         model.update(r);
 
         assertEquals(ITEM_COUNT * 2, model.getItemCount());
@@ -174,291 +170,6 @@
             assertEquals(i, c.getPosition());
         }
     }
-
-    // Tests sorting ascending by item name.
-    public void testSort_names_ascending() {
-        BitSet seen = new BitSet(ITEM_COUNT);
-        List<String> names = new ArrayList<>();
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_TITLE,
-                SortDimension.SORT_DIRECTION_ASCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = cursor;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        for (String id: model.getModelIds()) {
-            Cursor c = model.getItem(id);
-            seen.set(c.getPosition());
-            names.add(DocumentInfo.getCursorString(c, Document.COLUMN_DISPLAY_NAME));
-        }
-
-        assertEquals(ITEM_COUNT, seen.cardinality());
-        for (int i = 0; i < names.size()-1; ++i) {
-            assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
-        }
-    }
-
-    // Tests sorting descending by item name.
-    public void testSort_names_descending() {
-        BitSet seen = new BitSet(ITEM_COUNT);
-        List<String> names = new ArrayList<>();
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_TITLE,
-                SortDimension.SORT_DIRECTION_DESCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = cursor;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        for (String id: model.getModelIds()) {
-            Cursor c = model.getItem(id);
-            seen.set(c.getPosition());
-            names.add(DocumentInfo.getCursorString(c, Document.COLUMN_DISPLAY_NAME));
-        }
-
-        assertEquals(ITEM_COUNT, seen.cardinality());
-        for (int i = 0; i < names.size()-1; ++i) {
-            assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) >= 0);
-        }
-    }
-
-    // Tests sorting by item size.
-    public void testSort_sizes_ascending() {
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
-                SortDimension.SORT_DIRECTION_ASCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = cursor;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        BitSet seen = new BitSet(ITEM_COUNT);
-        int previousSize = Integer.MIN_VALUE;
-        for (String id: model.getModelIds()) {
-            Cursor c = model.getItem(id);
-            seen.set(c.getPosition());
-            // Check sort order - descending numerical
-            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
-            assertTrue(previousSize <= size);
-            previousSize = size;
-        }
-        // Check that all items were accounted for.
-        assertEquals(ITEM_COUNT, seen.cardinality());
-    }
-
-    // Tests sorting by item size.
-    public void testSort_sizes_descending() {
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
-                SortDimension.SORT_DIRECTION_DESCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = cursor;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        BitSet seen = new BitSet(ITEM_COUNT);
-        int previousSize = Integer.MAX_VALUE;
-        for (String id: model.getModelIds()) {
-            Cursor c = model.getItem(id);
-            seen.set(c.getPosition());
-            // Check sort order - descending numerical
-            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
-            assertTrue(previousSize >= size);
-            previousSize = size;
-        }
-        // Check that all items were accounted for.
-        assertEquals(ITEM_COUNT, seen.cardinality());
-    }
-
-    // Tests that directories and files are properly bucketed when sorting by size
-    public void testSort_sizesWithBucketing_ascending() {
-        MatrixCursor c = new MatrixCursor(COLUMNS);
-
-        for (int i = 0; i < ITEM_COUNT; ++i) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
-            row.add(Document.COLUMN_SIZE, i);
-            // Interleave directories and text files.
-            String mimeType =(i % 2 == 0) ? Document.MIME_TYPE_DIR : "text/*";
-            row.add(Document.COLUMN_MIME_TYPE, mimeType);
-        }
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
-                SortDimension.SORT_DIRECTION_ASCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = c;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        boolean seenAllDirs = false;
-        int previousSize = Integer.MIN_VALUE;
-        BitSet seen = new BitSet(ITEM_COUNT);
-        // Iterate over items in sort order. Once we've encountered a document (i.e. not a
-        // directory), all subsequent items must also be documents. That is, all directories are
-        // bucketed at the front of the list, sorted by size, followed by documents, sorted by size.
-        for (String id: model.getModelIds()) {
-            Cursor cOut = model.getItem(id);
-            seen.set(cOut.getPosition());
-
-            String mimeType = DocumentInfo.getCursorString(cOut, Document.COLUMN_MIME_TYPE);
-            if (seenAllDirs) {
-                assertFalse(Document.MIME_TYPE_DIR.equals(mimeType));
-            } else {
-                if (!Document.MIME_TYPE_DIR.equals(mimeType)) {
-                    seenAllDirs = true;
-                    // Reset the previous size seen, because documents are bucketed separately by
-                    // the sort.
-                    previousSize = Integer.MIN_VALUE;
-                }
-            }
-            // Check sort order - descending numerical
-            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
-            assertTrue(previousSize <= size);
-            previousSize = size;
-        }
-
-        // Check that all items were accounted for.
-        assertEquals(ITEM_COUNT, seen.cardinality());
-    }
-
-    // Tests that directories and files are properly bucketed when sorting by size
-    public void testSort_sizesWithBucketing_descending() {
-        MatrixCursor c = new MatrixCursor(COLUMNS);
-
-        for (int i = 0; i < ITEM_COUNT; ++i) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
-            row.add(Document.COLUMN_SIZE, i);
-            // Interleave directories and text files.
-            String mimeType =(i % 2 == 0) ? Document.MIME_TYPE_DIR : "text/*";
-            row.add(Document.COLUMN_MIME_TYPE, mimeType);
-        }
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
-                SortDimension.SORT_DIRECTION_DESCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = c;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        boolean seenAllDirs = false;
-        int previousSize = Integer.MAX_VALUE;
-        BitSet seen = new BitSet(ITEM_COUNT);
-        // Iterate over items in sort order. Once we've encountered a document (i.e. not a
-        // directory), all subsequent items must also be documents. That is, all directories are
-        // bucketed at the front of the list, sorted by size, followed by documents, sorted by size.
-        for (String id: model.getModelIds()) {
-            Cursor cOut = model.getItem(id);
-            seen.set(cOut.getPosition());
-
-            String mimeType = DocumentInfo.getCursorString(cOut, Document.COLUMN_MIME_TYPE);
-            if (seenAllDirs) {
-                assertFalse(Document.MIME_TYPE_DIR.equals(mimeType));
-            } else {
-                if (!Document.MIME_TYPE_DIR.equals(mimeType)) {
-                    seenAllDirs = true;
-                    // Reset the previous size seen, because documents are bucketed separately by
-                    // the sort.
-                    previousSize = Integer.MAX_VALUE;
-                }
-            }
-            // Check sort order - descending numerical
-            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
-            assertTrue(previousSize >= size);
-            previousSize = size;
-        }
-
-        // Check that all items were accounted for.
-        assertEquals(ITEM_COUNT, seen.cardinality());
-    }
-
-    public void testSort_time_ascending() {
-        final int DL_COUNT = 3;
-        MatrixCursor c = new MatrixCursor(COLUMNS);
-        Set<String> currentDownloads = new HashSet<>();
-
-        // Add some files
-        for (int i = 0; i < ITEM_COUNT; i++) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
-            row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
-        }
-        // Add some current downloads (no timestamp)
-        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            String id = Integer.toString(i);
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, id);
-            currentDownloads.add(id);
-        }
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_DATE,
-                SortDimension.SORT_DIRECTION_ASCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = c;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        String[] ids = model.getModelIds();
-
-        // Check that all items were accounted for
-        assertEquals(ITEM_COUNT + DL_COUNT, ids.length);
-
-        // Check that active downloads are sorted to the bottom.
-        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
-            assertTrue(currentDownloads.contains(ids[i]));
-        }
-    }
-
-    public void testSort_time_descending() {
-        final int DL_COUNT = 3;
-        MatrixCursor c = new MatrixCursor(COLUMNS);
-        Set<String> currentDownloads = new HashSet<>();
-
-        // Add some files
-        for (int i = 0; i < ITEM_COUNT; i++) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
-            row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
-        }
-        // Add some current downloads (no timestamp)
-        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
-            MatrixCursor.RowBuilder row = c.newRow();
-            String id = Integer.toString(i);
-            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
-            row.add(Document.COLUMN_DOCUMENT_ID, id);
-            currentDownloads.add(id);
-        }
-
-        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_DATE,
-                SortDimension.SORT_DIRECTION_DESCENDING);
-
-        DirectoryResult r = new DirectoryResult();
-        r.cursor = c;
-        r.sortModel = sortModel;
-        model.update(r);
-
-        String[] ids = model.getModelIds();
-
-        // Check that all items were accounted for
-        assertEquals(ITEM_COUNT + DL_COUNT, ids.length);
-
-        // Check that active downloads are sorted to the top.
-        for (int i = 0; i < DL_COUNT; i++) {
-            assertTrue(currentDownloads.contains(ids[i]));
-        }
-    }
-
     private void setupTestContext() {
         final MockContentResolver resolver = new MockContentResolver();
         new ContextWrapper(getContext()) {
diff --git a/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java b/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
index dec287b..d44a467 100644
--- a/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
+++ b/tests/unit/com/android/documentsui/dirlist/SectionBreakDocumentsAdapterWrapperTest.java
@@ -77,7 +77,6 @@
         }
         DirectoryResult r = new DirectoryResult();
         r.cursor = c;
-        r.sortModel = SortModels.createTestSortModel();
         mModel.update(r);
 
         assertEquals(mModel.getItemCount(), mAdapter.getItemCount());
@@ -103,7 +102,6 @@
         }
         DirectoryResult r = new DirectoryResult();
         r.cursor = c;
-        r.sortModel = SortModels.createTestSortModel();
         mModel.update(r);
 
         assertEquals(mModel.getItemCount() + 1, mAdapter.getItemCount());
diff --git a/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java b/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java
new file mode 100644
index 0000000..1d6a09c
--- /dev/null
+++ b/tests/unit/com/android/documentsui/sorting/SortingCursorWrapperTest.java
@@ -0,0 +1,377 @@
+/*
+ * Copyright (C) 2016 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.documentsui.sorting;
+
+import static com.android.documentsui.base.DocumentInfo.getCursorString;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertFalse;
+import static junit.framework.Assert.assertTrue;
+
+import android.database.Cursor;
+import android.database.MatrixCursor;
+import android.provider.DocumentsContract.Document;
+import android.support.test.runner.AndroidJUnit4;
+
+import com.android.documentsui.base.DocumentInfo;
+import com.android.documentsui.base.Shared;
+import com.android.documentsui.roots.RootCursorWrapper;
+import com.android.documentsui.sorting.SortModel.SortDimensionId;
+import com.android.documentsui.testing.SortModels;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Random;
+import java.util.Set;
+
+@RunWith(AndroidJUnit4.class)
+public class SortingCursorWrapperTest {
+    private static final int ITEM_COUNT = 10;
+    private static final String AUTHORITY = "test_authority";
+
+    private static final String[] COLUMNS = new String[]{
+            RootCursorWrapper.COLUMN_AUTHORITY,
+            Document.COLUMN_DOCUMENT_ID,
+            Document.COLUMN_FLAGS,
+            Document.COLUMN_DISPLAY_NAME,
+            Document.COLUMN_SIZE,
+            Document.COLUMN_LAST_MODIFIED,
+            Document.COLUMN_MIME_TYPE
+    };
+
+    private static final String[] NAMES = new String[] {
+            "4",
+            "foo",
+            "1",
+            "bar",
+            "*(Ljifl;a",
+            "0",
+            "baz",
+            "2",
+            "3",
+            "%$%VD"
+    };
+
+    private SortModel sortModel;
+    private Cursor cursor;
+
+    @Before
+    public void setUp() {
+        sortModel = SortModels.createTestSortModel();
+
+        Random rand = new Random();
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+        for (int i = 0; i < ITEM_COUNT; ++i) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_FLAGS, Document.FLAG_SUPPORTS_DELETE);
+            // Generate random document names and sizes. This forces the model's internal sort code
+            // to actually do something.
+            row.add(Document.COLUMN_DISPLAY_NAME, NAMES[i]);
+            row.add(Document.COLUMN_SIZE, rand.nextInt());
+        }
+
+        cursor = c;
+    }
+
+    // Tests sorting ascending by item name.
+    @Test
+    public void testSort_names_ascending() {
+        BitSet seen = new BitSet(ITEM_COUNT);
+        List<String> names = new ArrayList<>();
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_TITLE,
+                SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper();
+
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(Integer.parseInt(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+            names.add(getCursorString(cursor, Document.COLUMN_DISPLAY_NAME));
+        }
+
+        assertEquals(ITEM_COUNT, seen.cardinality());
+        for (int i = 0; i < names.size()-1; ++i) {
+            assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) <= 0);
+        }
+    }
+
+    // Tests sorting descending by item name.
+    @Test
+    public void testSort_names_descending() {
+        BitSet seen = new BitSet(ITEM_COUNT);
+        List<String> names = new ArrayList<>();
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_TITLE,
+                SortDimension.SORT_DIRECTION_DESCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper();
+
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(Integer.parseInt(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+            names.add(getCursorString(cursor, Document.COLUMN_DISPLAY_NAME));
+        }
+
+        assertEquals(ITEM_COUNT, seen.cardinality());
+        for (int i = 0; i < names.size()-1; ++i) {
+            assertTrue(Shared.compareToIgnoreCaseNullable(names.get(i), names.get(i+1)) >= 0);
+        }
+    }
+
+    // Tests sorting by item size.
+    @Test
+    public void testSort_sizes_ascending() {
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
+                SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper();
+
+        BitSet seen = new BitSet(ITEM_COUNT);
+        int previousSize = Integer.MIN_VALUE;
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(Integer.parseInt(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+            // Check sort order - descending numerical
+            int size = DocumentInfo.getCursorInt(cursor, Document.COLUMN_SIZE);
+            assertTrue(previousSize <= size);
+            previousSize = size;
+        }
+        // Check that all items were accounted for.
+        assertEquals(ITEM_COUNT, seen.cardinality());
+    }
+
+    // Tests sorting by item size.
+    @Test
+    public void testSort_sizes_descending() {
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
+                SortDimension.SORT_DIRECTION_DESCENDING);
+
+        Cursor cursor = createSortingCursorWrapper();
+
+        BitSet seen = new BitSet(ITEM_COUNT);
+        int previousSize = Integer.MAX_VALUE;
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(Integer.parseInt(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+            // Check sort order - descending numerical
+            int size = DocumentInfo.getCursorInt(cursor, Document.COLUMN_SIZE);
+            assertTrue(previousSize >= size);
+            previousSize = size;
+        }
+        // Check that all items were accounted for.
+        assertEquals(ITEM_COUNT, seen.cardinality());
+    }
+
+    // Tests that directories and files are properly bucketed when sorting by size
+    @Test
+    public void testSort_sizesWithBucketing_ascending() {
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+
+        for (int i = 0; i < ITEM_COUNT; ++i) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_SIZE, i);
+            // Interleave directories and text files.
+            String mimeType =(i % 2 == 0) ? Document.MIME_TYPE_DIR : "text/*";
+            row.add(Document.COLUMN_MIME_TYPE, mimeType);
+        }
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
+                SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper(c);
+
+        boolean seenAllDirs = false;
+        int previousSize = Integer.MIN_VALUE;
+        BitSet seen = new BitSet(ITEM_COUNT);
+        // Iterate over items in sort order. Once we've encountered a document (i.e. not a
+        // directory), all subsequent items must also be documents. That is, all directories are
+        // bucketed at the front of the list, sorted by size, followed by documents, sorted by size.
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(Integer.parseInt(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+
+            String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            if (seenAllDirs) {
+                assertFalse(Document.MIME_TYPE_DIR.equals(mimeType));
+            } else {
+                if (!Document.MIME_TYPE_DIR.equals(mimeType)) {
+                    seenAllDirs = true;
+                    // Reset the previous size seen, because documents are bucketed separately by
+                    // the sort.
+                    previousSize = Integer.MIN_VALUE;
+                }
+            }
+            // Check sort order - descending numerical
+            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
+            assertTrue(previousSize <= size);
+            previousSize = size;
+        }
+
+        // Check that all items were accounted for.
+        assertEquals(ITEM_COUNT, seen.cardinality());
+    }
+
+    // Tests that directories and files are properly bucketed when sorting by size
+    @Test
+    public void testSort_sizesWithBucketing_descending() {
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+
+        for (int i = 0; i < ITEM_COUNT; ++i) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_SIZE, i);
+            // Interleave directories and text files.
+            String mimeType =(i % 2 == 0) ? Document.MIME_TYPE_DIR : "text/*";
+            row.add(Document.COLUMN_MIME_TYPE, mimeType);
+        }
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_SIZE,
+                SortDimension.SORT_DIRECTION_DESCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper(c);
+
+        boolean seenAllDirs = false;
+        int previousSize = Integer.MAX_VALUE;
+        BitSet seen = new BitSet(ITEM_COUNT);
+        // Iterate over items in sort order. Once we've encountered a document (i.e. not a
+        // directory), all subsequent items must also be documents. That is, all directories are
+        // bucketed at the front of the list, sorted by size, followed by documents, sorted by size.
+        for (int i = 0; i < cursor.getCount(); ++i) {
+            cursor.moveToPosition(i);
+            seen.set(cursor.getPosition());
+
+            String mimeType = getCursorString(cursor, Document.COLUMN_MIME_TYPE);
+            if (seenAllDirs) {
+                assertFalse(Document.MIME_TYPE_DIR.equals(mimeType));
+            } else {
+                if (!Document.MIME_TYPE_DIR.equals(mimeType)) {
+                    seenAllDirs = true;
+                    // Reset the previous size seen, because documents are bucketed separately by
+                    // the sort.
+                    previousSize = Integer.MAX_VALUE;
+                }
+            }
+            // Check sort order - descending numerical
+            int size = DocumentInfo.getCursorInt(c, Document.COLUMN_SIZE);
+            assertTrue(previousSize >= size);
+            previousSize = size;
+        }
+
+        // Check that all items were accounted for.
+        assertEquals(ITEM_COUNT, seen.cardinality());
+    }
+
+    @Test
+    public void testSort_time_ascending() {
+        final int DL_COUNT = 3;
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+        Set<String> currentDownloads = new HashSet<>();
+
+        // Add some files
+        for (int i = 0; i < ITEM_COUNT; i++) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
+        }
+        // Add some current downloads (no timestamp)
+        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            String id = Integer.toString(i);
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, id);
+            currentDownloads.add(id);
+        }
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_DATE,
+                SortDimension.SORT_DIRECTION_ASCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper(c);
+
+        // Check that all items were accounted for
+        assertEquals(ITEM_COUNT + DL_COUNT, cursor.getCount());
+
+        // Check that active downloads are sorted to the bottom.
+        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
+            assertTrue(currentDownloads.contains(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+        }
+    }
+
+    @Test
+    public void testSort_time_descending() {
+        final int DL_COUNT = 3;
+        MatrixCursor c = new MatrixCursor(COLUMNS);
+        Set<String> currentDownloads = new HashSet<>();
+
+        // Add some files
+        for (int i = 0; i < ITEM_COUNT; i++) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, Integer.toString(i));
+            row.add(Document.COLUMN_LAST_MODIFIED, System.currentTimeMillis());
+        }
+        // Add some current downloads (no timestamp)
+        for (int i = ITEM_COUNT; i < ITEM_COUNT + DL_COUNT; i++) {
+            MatrixCursor.RowBuilder row = c.newRow();
+            String id = Integer.toString(i);
+            row.add(RootCursorWrapper.COLUMN_AUTHORITY, AUTHORITY);
+            row.add(Document.COLUMN_DOCUMENT_ID, id);
+            currentDownloads.add(id);
+        }
+
+        sortModel.sortByUser(SortModel.SORT_DIMENSION_ID_DATE,
+                SortDimension.SORT_DIRECTION_DESCENDING);
+
+        final Cursor cursor = createSortingCursorWrapper(c);
+
+        // Check that all items were accounted for
+        assertEquals(ITEM_COUNT + DL_COUNT, cursor.getCount());
+
+        // Check that active downloads are sorted to the top.
+        for (int i = 0; i < DL_COUNT; i++) {
+            assertTrue(currentDownloads.contains(
+                    DocumentInfo.getCursorString(cursor, Document.COLUMN_DOCUMENT_ID)));
+        }
+    }
+
+    private Cursor createSortingCursorWrapper() {
+        return createSortingCursorWrapper(cursor);
+    }
+
+    private Cursor createSortingCursorWrapper(Cursor c) {
+        final @SortDimensionId int id = sortModel.getSortedDimensionId();
+        return new SortingCursorWrapper(c, sortModel.getDimensionById(id));
+    }
+}
