diff --git a/src/com/android/launcher3/AlphabeticalAppsList.java b/src/com/android/launcher3/AlphabeticalAppsList.java
new file mode 100644
index 0000000..2847afc
--- /dev/null
+++ b/src/com/android/launcher3/AlphabeticalAppsList.java
@@ -0,0 +1,242 @@
+package com.android.launcher3;
+
+import android.content.ComponentName;
+import android.content.Context;
+import android.support.v7.widget.RecyclerView;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+
+/**
+ * The alphabetically sorted list of applications.
+ */
+public class AlphabeticalAppsList {
+
+    /**
+     * Info about a section in the alphabetic list
+     */
+    public class SectionInfo {
+        public String sectionName;
+        public int numAppsInSection;
+    }
+
+    /**
+     * A filter interface to limit the set of applications in the apps list.
+     */
+    public interface Filter {
+        public boolean retainApp(AppInfo info);
+    }
+
+    // Hack to force RecyclerView to break sections
+    public static final AppInfo SECTION_BREAK_INFO = null;
+
+    private List<AppInfo> mApps = new ArrayList<>();
+    private List<AppInfo> mFilteredApps = new ArrayList<>();
+    private List<AppInfo> mSectionedFilteredApps = new ArrayList<>();
+    private List<SectionInfo> mSections = new ArrayList<>();
+    private RecyclerView.Adapter mAdapter;
+    private Filter mFilter;
+    private AlphabeticIndexCompat mIndexer;
+
+    public AlphabeticalAppsList(Context context) {
+        mIndexer = new AlphabeticIndexCompat(context);
+    }
+
+    /**
+     * Sets the adapter to notify when this dataset changes.
+     */
+    public void setAdapter(RecyclerView.Adapter adapter) {
+        mAdapter = adapter;
+    }
+
+    /**
+     * Returns sections of all the current filtered applications.
+     */
+    public List<SectionInfo> getSections() {
+        return mSections;
+    }
+
+    /**
+     * Returns the current filtered list of applications broken down into their sections.
+     */
+    public List<AppInfo> getApps() {
+        return mSectionedFilteredApps;
+    }
+
+    /**
+     * Returns the current filtered list of applications.
+     */
+    public List<AppInfo> getAppsWithoutSectionBreaks() {
+        return mFilteredApps;
+    }
+
+    /**
+     * Returns the section name for the application.
+     */
+    public String getSectionNameForApp(AppInfo info) {
+        String title = info.title.toString();
+        String sectionName = mIndexer.getBucketLabel(mIndexer.getBucketIndex(title));
+        return sectionName;
+    }
+
+    /**
+     * Returns the indexer for this locale.
+     */
+    public AlphabeticIndexCompat getIndexer() {
+        return mIndexer;
+    }
+
+    /**
+     * Sets the current filter for this list of apps.
+     */
+    public void setFilter(Filter f) {
+        mFilter = f;
+        onAppsUpdated();
+        mAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Sets the current set of apps.
+     */
+    public void setApps(List<AppInfo> apps) {
+        Collections.sort(apps, LauncherModel.getAppNameComparator());
+        mApps.clear();
+        mApps.addAll(apps);
+        onAppsUpdated();
+        mAdapter.notifyDataSetChanged();
+    }
+
+    /**
+     * Adds new apps to the list.
+     */
+    public void addApps(List<AppInfo> apps) {
+        // We add it in place, in alphabetical order
+        for (AppInfo info : apps) {
+            addApp(info);
+        }
+    }
+
+    /**
+     * Updates existing apps in the list
+     */
+    public void updateApps(List<AppInfo> apps) {
+        for (AppInfo info : apps) {
+            int index = mApps.indexOf(info);
+            if (index != -1) {
+                mApps.set(index, info);
+                onAppsUpdated();
+                mAdapter.notifyItemChanged(index);
+            } else {
+                addApp(info);
+            }
+        }
+    }
+
+    /**
+     * Removes some apps from the list.
+     */
+    public void removeApps(List<AppInfo> apps) {
+        for (AppInfo info : apps) {
+            int removeIndex = findAppByComponent(mApps, info);
+            if (removeIndex != -1) {
+                int sectionedIndex = mSectionedFilteredApps.indexOf(info);
+                int numAppsInSection = numAppsInSection(info);
+                mApps.remove(removeIndex);
+                onAppsUpdated();
+                if (numAppsInSection == 1) {
+                    // Remove the section and the icon
+                    mAdapter.notifyItemRemoved(sectionedIndex - 1);
+                    mAdapter.notifyItemRemoved(sectionedIndex - 1);
+                } else {
+                    mAdapter.notifyItemRemoved(sectionedIndex);
+                }
+            }
+        }
+    }
+
+    /**
+     * Finds the index of an app given a target AppInfo.
+     */
+    private int findAppByComponent(List<AppInfo> apps, AppInfo targetInfo) {
+        ComponentName targetComponent = targetInfo.intent.getComponent();
+        int length = apps.size();
+        for (int i = 0; i < length; ++i) {
+            AppInfo info = apps.get(i);
+            if (info.user.equals(info.user)
+                    && info.intent.getComponent().equals(targetComponent)) {
+                return i;
+            }
+        }
+        return -1;
+    }
+
+    /**
+     * Implementation to actually add an app to the alphabetic list
+     */
+    private void addApp(AppInfo info) {
+        Comparator<AppInfo> appNameComparator = LauncherModel.getAppNameComparator();
+        int index = Collections.binarySearch(mApps, info, appNameComparator);
+        if (index < 0) {
+            mApps.add(-(index + 1), info);
+            onAppsUpdated();
+
+            int sectionedIndex = mSectionedFilteredApps.indexOf(info);
+            int numAppsInSection = numAppsInSection(info);
+            if (numAppsInSection == 1) {
+                // New section added along with icon
+                mAdapter.notifyItemInserted(sectionedIndex - 1);
+                mAdapter.notifyItemInserted(sectionedIndex - 1);
+            } else {
+                mAdapter.notifyItemInserted(sectionedIndex);
+            }
+        }
+    }
+
+    /**
+     * Returns the number of apps in the section that the given info is in.
+     */
+    private int numAppsInSection(AppInfo info) {
+        int appIndex = mFilteredApps.indexOf(info);
+        int appCount = 0;
+        for (SectionInfo section : mSections) {
+            if (appCount + section.numAppsInSection > appIndex) {
+                return section.numAppsInSection;
+            }
+            appCount += section.numAppsInSection;
+        }
+        return 1;
+    }
+
+    /**
+     * Updates internals when the set of apps are updated.
+     */
+    private void onAppsUpdated() {
+        // Recreate the filtered apps
+        mFilteredApps.clear();
+        for (AppInfo info : mApps) {
+            if (mFilter == null || mFilter.retainApp(info)) {
+                mFilteredApps.add(info);
+            }
+        }
+
+        // Section the apps (for convenience for the grid layout)
+        mSections.clear();
+        mSectionedFilteredApps.clear();
+        SectionInfo lastSectionInfo = null;
+        for (AppInfo info : mFilteredApps) {
+            String sectionName = getSectionNameForApp(info);
+            if (lastSectionInfo == null || !lastSectionInfo.sectionName.equals(sectionName)) {
+                lastSectionInfo = new SectionInfo();
+                lastSectionInfo.sectionName = sectionName;
+                mSectionedFilteredApps.add(SECTION_BREAK_INFO);
+                mSections.add(lastSectionInfo);
+            }
+            lastSectionInfo.numAppsInSection++;
+            mSectionedFilteredApps.add(info);
+        }
+    }
+}
diff --git a/src/com/android/launcher3/AppsContainerRecyclerView.java b/src/com/android/launcher3/AppsContainerRecyclerView.java
new file mode 100644
index 0000000..2280e99
--- /dev/null
+++ b/src/com/android/launcher3/AppsContainerRecyclerView.java
@@ -0,0 +1,271 @@
+/*
+ * Copyright (C) 2015 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.launcher3;
+
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.graphics.drawable.Drawable;
+import android.support.v7.widget.RecyclerView;
+import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.view.ViewConfiguration;
+
+import java.util.List;
+
+/**
+ * A RecyclerView with custom fastscroll support.  This is the main container for the all apps
+ * icons.
+ */
+public class AppsContainerRecyclerView extends RecyclerView
+        implements RecyclerView.OnItemTouchListener {
+
+    private AlphabeticalAppsList mApps;
+    private int mNumAppsPerRow;
+
+    private Drawable mFastScrollerBg;
+    private boolean mDraggingFastScroller;
+    private String mFastScrollSectionName;
+    private Paint mFastScrollTextPaint;
+    private Rect mFastScrollTextBounds = new Rect();
+    private float mFastScrollAlpha;
+    private int mDownX;
+    private int mDownY;
+    private int mLastX;
+    private int mLastY;
+    private int mGutterSize;
+
+    public AppsContainerRecyclerView(Context context) {
+        this(context, null);
+    }
+
+    public AppsContainerRecyclerView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+
+    public AppsContainerRecyclerView(Context context, AttributeSet attrs, int defStyleAttr) {
+        this(context, attrs, defStyleAttr, 0);
+    }
+
+    public AppsContainerRecyclerView(Context context, AttributeSet attrs, int defStyleAttr,
+            int defStyleRes) {
+        super(context, attrs, defStyleAttr);
+
+        Resources res = context.getResources();
+        int fastScrollerSize = res.getDimensionPixelSize(R.dimen.apps_view_fast_scroll_popup_size);
+        mFastScrollerBg = res.getDrawable(R.drawable.apps_list_fastscroll_bg);
+        mFastScrollerBg.setBounds(0, 0, fastScrollerSize, fastScrollerSize);
+        mFastScrollTextPaint = new Paint();
+        mFastScrollTextPaint.setColor(Color.WHITE);
+        mFastScrollTextPaint.setAntiAlias(true);
+        mFastScrollTextPaint.setTextSize(res.getDimensionPixelSize(
+                R.dimen.apps_view_fast_scroll_text_size));
+        mGutterSize = res.getDimensionPixelSize(R.dimen.apps_view_fast_scroll_gutter_size);
+        setFastScrollerAlpha(getFastScrollerAlpha());
+    }
+
+    /**
+     * Sets the list of apps in this view, used to determine the fastscroll position.
+     */
+    public void setApps(AlphabeticalAppsList apps) {
+        mApps = apps;
+    }
+
+    /**
+     * Sets the number of apps per row in this recycler view.
+     */
+    public void setNumAppsPerRow(int rowSize) {
+        mNumAppsPerRow = rowSize;
+    }
+
+    /**
+     * Sets the fast scroller alpha.
+     */
+    public void setFastScrollerAlpha(float alpha) {
+        mFastScrollAlpha = alpha;
+        invalidateFastScroller();
+    }
+
+    /**
+     * Gets the fast scroller alpha.
+     */
+    public float getFastScrollerAlpha() {
+        return mFastScrollAlpha;
+    }
+
+    @Override
+    protected void onFinishInflate() {
+        addOnItemTouchListener(this);
+    }
+
+    @Override
+    protected void dispatchDraw(Canvas canvas) {
+        super.dispatchDraw(canvas);
+
+        if (mFastScrollAlpha > 0f) {
+            boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
+                    LAYOUT_DIRECTION_RTL);
+            Rect bgBounds = mFastScrollerBg.getBounds();
+            int restoreCount = canvas.save(Canvas.MATRIX_SAVE_FLAG);
+            int x;
+            if (isRtl) {
+                x = getPaddingLeft() + getScrollBarSize();
+            } else {
+                x = getWidth() - getPaddingRight() - getScrollBarSize() - bgBounds.width();
+            }
+            int y = mLastY - bgBounds.height() / 2;
+            y = Math.max(getPaddingTop(), Math.min(y, getHeight() - getPaddingBottom() -
+                    bgBounds.height()));
+            canvas.translate(x, y);
+            mFastScrollerBg.setAlpha((int) (mFastScrollAlpha * 255));
+            mFastScrollerBg.draw(canvas);
+            mFastScrollTextPaint.setAlpha((int) (mFastScrollAlpha * 255));
+            mFastScrollTextPaint.getTextBounds(mFastScrollSectionName, 0,
+                    mFastScrollSectionName.length(), mFastScrollTextBounds);
+            canvas.drawText(mFastScrollSectionName,
+                    (bgBounds.width() - mFastScrollTextBounds.width()) / 2,
+                    bgBounds.height() -  (bgBounds.height() - mFastScrollTextBounds.height()) / 2,
+                    mFastScrollTextPaint);
+            canvas.restoreToCount(restoreCount);
+        }
+    }
+
+    /**
+     * We intercept the touch handling only to support fast scrolling when initiated from the
+     * gutter.  Otherwise, we fall back to the default RecyclerView touch handling.
+     */
+    @Override
+    public boolean onInterceptTouchEvent(RecyclerView rv, MotionEvent ev) {
+        return handleTouchEvent(ev);
+    }
+
+    @Override
+    public void onTouchEvent(RecyclerView rv, MotionEvent ev) {
+        handleTouchEvent(ev);
+    }
+
+    /**
+     * Handles the touch event and determines whether to show the fast scroller (or updates it if
+     * it is already showing).
+     */
+    private boolean handleTouchEvent(MotionEvent ev) {
+        ViewConfiguration config = ViewConfiguration.get(getContext());
+
+        int action = ev.getAction();
+        int x = (int) ev.getX();
+        int y = (int) ev.getY();
+        switch (action) {
+            case MotionEvent.ACTION_DOWN:
+                // Keep track of the down positions
+                mDownX = mLastX = x;
+                mDownY = mLastY = y;
+                stopScroll();
+                break;
+            case MotionEvent.ACTION_MOVE:
+                // Check if we are scrolling
+                boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
+                        LAYOUT_DIRECTION_RTL);
+                boolean isInGutter;
+                if (isRtl) {
+                    isInGutter = mDownX < mGutterSize;
+                } else {
+                    isInGutter = mDownX >= (getWidth() - mGutterSize);
+                }
+                if (!mDraggingFastScroller && isInGutter &&
+                        Math.abs(y - mDownY) > config.getScaledTouchSlop()) {
+                    getParent().requestDisallowInterceptTouchEvent(true);
+                    mDraggingFastScroller = true;
+                    animateFastScrollerVisibility(true);
+                }
+                if (mDraggingFastScroller) {
+                    mLastX = x;
+                    mLastY = y;
+
+                    // Scroll to the right position, and update the section name
+                    int top = getPaddingTop() + (mFastScrollerBg.getBounds().height() / 2);
+                    int bottom = getHeight() - getPaddingBottom() -
+                            (mFastScrollerBg.getBounds().height() / 2);
+                    float boundedY = (float) Math.max(top, Math.min(bottom, y));
+                    mFastScrollSectionName = scrollToPositionAtProgress((boundedY - top) /
+                            (bottom - top));
+                    invalidateFastScroller();
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+            case MotionEvent.ACTION_CANCEL:
+                mDraggingFastScroller = false;
+                animateFastScrollerVisibility(false);
+                break;
+        }
+        return mDraggingFastScroller;
+
+    }
+
+    /**
+     * Animates the visibility of the fast scroller popup.
+     */
+    private void animateFastScrollerVisibility(boolean visible) {
+        ObjectAnimator anim = ObjectAnimator.ofFloat(this, "fastScrollerAlpha", visible ? 1f : 0f);
+        anim.setDuration(visible ? 200 : 150);
+        anim.start();
+    }
+
+    /**
+     * Invalidates the fast scroller popup.
+     */
+    private void invalidateFastScroller() {
+        invalidate(getWidth() - getPaddingRight() - getScrollBarSize() -
+                mFastScrollerBg.getIntrinsicWidth(), 0, getWidth(), getHeight());
+    }
+
+    /**
+     * Maps the progress (from 0..1) to the position that should be visible
+     */
+    private String scrollToPositionAtProgress(float progress) {
+        List<AlphabeticalAppsList.SectionInfo> sections = mApps.getSections();
+        // Get the total number of rows
+        int rowCount = 0;
+        for (AlphabeticalAppsList.SectionInfo info : sections) {
+            int numRowsInSection = (int) Math.ceil((float) info.numAppsInSection / mNumAppsPerRow);
+            rowCount += numRowsInSection;
+        }
+
+        // Find the index of the first app in that row and scroll to that position
+        int rowAtProgress = (int) (progress * rowCount);
+        int appIndex = 0;
+        rowCount = 0;
+        for (AlphabeticalAppsList.SectionInfo info : sections) {
+            int numRowsInSection = (int) Math.ceil((float) info.numAppsInSection / mNumAppsPerRow);
+            if (rowCount + numRowsInSection > rowAtProgress) {
+                appIndex += (rowAtProgress - rowCount) * mNumAppsPerRow;
+                break;
+            }
+            rowCount += numRowsInSection;
+            appIndex += info.numAppsInSection;
+        }
+        appIndex = Math.max(0, Math.min(mApps.getAppsWithoutSectionBreaks().size() - 1, appIndex));
+        AppInfo appInfo = mApps.getAppsWithoutSectionBreaks().get(appIndex);
+        int sectionedAppIndex = mApps.getApps().indexOf(appInfo);
+        scrollToPosition(sectionedAppIndex);
+
+        // Returns the section name of the row
+        return mApps.getSectionNameForApp(appInfo);
+    }
+}
diff --git a/src/com/android/launcher3/AppsContainerView.java b/src/com/android/launcher3/AppsContainerView.java
index cabacec..cc31e20 100644
--- a/src/com/android/launcher3/AppsContainerView.java
+++ b/src/com/android/launcher3/AppsContainerView.java
@@ -1,409 +1,64 @@
+/*
+ * Copyright (C) 2015 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.launcher3;
 
-import android.content.ComponentName;
 import android.content.Context;
 import android.graphics.Point;
 import android.graphics.Rect;
+import android.support.v7.widget.RecyclerView;
+import android.text.Editable;
+import android.text.TextWatcher;
 import android.util.AttributeSet;
-import android.view.Gravity;
-import android.view.LayoutInflater;
+import android.view.KeyEvent;
 import android.view.MotionEvent;
 import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.EditText;
 import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-import android.widget.ListView;
-import android.widget.SectionIndexer;
 import android.widget.TextView;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.LinkedHashMap;
 import java.util.List;
-import java.util.Map;
 
 
 /**
- * Represents a row in the apps list view.
- */
-class AppsRow {
-    int sectionId;
-    String sectionDescription;
-    List<AppInfo> apps;
-
-    public AppsRow(int sId, String sc, List<AppInfo> ai) {
-        sectionId = sId;
-        sectionDescription = sc;
-        apps = ai;
-    }
-
-    public AppsRow(int sId, List<AppInfo> ai) {
-        sectionId = sId;
-        apps = ai;
-    }
-}
-
-/**
- * An interface to an algorithm that generates app rows.
- */
-interface AppRowAlgorithm {
-    public List<AppsRow> computeAppRows(List<AppInfo> sortedApps, int appsPerRow);
-    public int getIconViewLayoutId();
-    public int getRowViewLayoutId();
-    public void bindRowViewIconToInfo(BubbleTextView icon, AppInfo info);
-}
-
-/**
- * Computes the rows in the apps list view.
- */
-class SectionedAppsAlgorithm implements AppRowAlgorithm {
-
-    @Override
-    public List<AppsRow> computeAppRows(List<AppInfo> sortedApps, int appsPerRow) {
-        List<AppsRow> rows = new ArrayList<>();
-        LinkedHashMap<String, List<AppInfo>> sections = computeSectionedApps(sortedApps);
-        int sectionId = 0;
-        for (Map.Entry<String, List<AppInfo>> sectionEntry : sections.entrySet()) {
-            String section = sectionEntry.getKey();
-            List<AppInfo> apps = sectionEntry.getValue();
-            int numRows = (int) Math.ceil((float) apps.size() / appsPerRow);
-            for (int i = 0; i < numRows; i++) {
-                List<AppInfo> appsInRow = new ArrayList<>();
-                int offset = i * appsPerRow;
-                for (int j = 0; j < appsPerRow; j++) {
-                    if (offset + j < apps.size()) {
-                        appsInRow.add(apps.get(offset + j));
-                    }
-                }
-                if (i == 0) {
-                    rows.add(new AppsRow(sectionId, section, appsInRow));
-                } else {
-                    rows.add(new AppsRow(sectionId, appsInRow));
-                }
-            }
-            sectionId++;
-        }
-        return rows;
-    }
-
-    @Override
-    public int getIconViewLayoutId() {
-        return R.layout.apps_grid_row_icon_view;
-    }
-
-    @Override
-    public int getRowViewLayoutId() {
-        return R.layout.apps_grid_row_view;
-    }
-
-    private LinkedHashMap<String, List<AppInfo>> computeSectionedApps(List<AppInfo> sortedApps) {
-        LinkedHashMap<String, List<AppInfo>> sections = new LinkedHashMap<>();
-        for (AppInfo info : sortedApps) {
-            String section = getSection(info);
-            List<AppInfo> sectionApps = sections.get(section);
-            if (sectionApps == null) {
-                sectionApps = new ArrayList<>();
-                sections.put(section, sectionApps);
-            }
-            sectionApps.add(info);
-        }
-        return sections;
-    }
-
-    @Override
-    public void bindRowViewIconToInfo(BubbleTextView icon, AppInfo info) {
-        icon.applyFromApplicationInfo(info);
-    }
-
-    private String getSection(AppInfo app) {
-        return app.title.toString().substring(0, 1).toLowerCase();
-    }
-}
-
-/**
- * Computes the rows in the apps grid view.
- */
-class ListedAppsAlgorithm implements AppRowAlgorithm {
-
-    @Override
-    public List<AppsRow> computeAppRows(List<AppInfo> sortedApps, int appsPerRow) {
-        List<AppsRow> rows = new ArrayList<>();
-        int sectionId = -1;
-        String prevSection = "";
-        for (AppInfo info : sortedApps) {
-            List<AppInfo> appsInRow = new ArrayList<>();
-            appsInRow.add(info);
-            String section = getSection(info);
-            if (!prevSection.equals(section)) {
-                prevSection = section;
-                sectionId++;
-                rows.add(new AppsRow(sectionId, section, appsInRow));
-            } else {
-                rows.add(new AppsRow(sectionId, appsInRow));
-            }
-        }
-        return rows;
-    }
-
-    @Override
-    public int getIconViewLayoutId() {
-        return R.layout.apps_list_row_icon_view;
-    }
-
-    @Override
-    public int getRowViewLayoutId() {
-        return R.layout.apps_list_row_view;
-    }
-
-    @Override
-    public void bindRowViewIconToInfo(BubbleTextView icon, AppInfo info) {
-        icon.applyFromApplicationInfo(info);
-    }
-
-    private String getSection(AppInfo app) {
-        return app.title.toString().substring(0, 1).toLowerCase();
-    }
-}
-
-/**
- * The adapter of all the apps
- */
-class AppsListAdapter extends BaseAdapter implements SectionIndexer {
-
-    private LayoutInflater mLayoutInflater;
-    private List<AppsRow> mAppRows = new ArrayList<>();
-    private View.OnTouchListener mTouchListener;
-    private View.OnClickListener mIconClickListener;
-    private View.OnLongClickListener mIconLongClickListener;
-    private AppRowAlgorithm mRowAlgorithm;
-    private int mAppsPerRow;
-
-    public AppsListAdapter(Context context, View.OnTouchListener touchListener,
-            View.OnClickListener iconClickListener, View.OnLongClickListener iconLongClickListener) {
-        mLayoutInflater = LayoutInflater.from(context);
-        mTouchListener = touchListener;
-        mIconClickListener = iconClickListener;
-        mIconLongClickListener = iconLongClickListener;
-    }
-
-    void setApps(List<AppsRow> apps, int appsPerRow, AppRowAlgorithm algo) {
-        mAppsPerRow = appsPerRow;
-        mRowAlgorithm = algo;
-        mAppRows.clear();
-        mAppRows.addAll(apps);
-        notifyDataSetChanged();
-    }
-
-    @Override
-    public int getCount() {
-        return mAppRows.size();
-    }
-
-    @Override
-    public Object getItem(int position) {
-        return mAppRows.get(position);
-    }
-
-    @Override
-    public long getItemId(int position) {
-        return position;
-    }
-
-    @Override
-    public View getView(int position, View convertView, ViewGroup parent) {
-        AppsRow info = mAppRows.get(position);
-        ViewGroup row = (ViewGroup) convertView;
-        if (row == null) {
-            // Inflate the row and all the icon children necessary
-            row = (ViewGroup) mLayoutInflater.inflate(mRowAlgorithm.getRowViewLayoutId(),
-                    parent, false);
-            for (int i = 0; i < mAppsPerRow; i++) {
-                BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
-                        mRowAlgorithm.getIconViewLayoutId(), row, false);
-                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0,
-                        ViewGroup.LayoutParams.WRAP_CONTENT, 1);
-                lp.gravity = Gravity.CENTER_VERTICAL;
-                icon.setLayoutParams(lp);
-                icon.setOnTouchListener(mTouchListener);
-                icon.setOnClickListener(mIconClickListener);
-                icon.setOnLongClickListener(mIconLongClickListener);
-                icon.setFocusable(true);
-                row.addView(icon);
-            }
-        }
-        // Bind the section header
-        TextView tv = (TextView) row.findViewById(R.id.section);
-        if (info.sectionDescription != null) {
-            tv.setText(info.sectionDescription);
-            tv.setVisibility(View.VISIBLE);
-        } else {
-            tv.setVisibility(View.INVISIBLE);
-        }
-        // Bind the icons
-        for (int i = 0; i < mAppsPerRow; i++) {
-            BubbleTextView icon = (BubbleTextView) row.getChildAt(i + 1);
-            if (i < info.apps.size()) {
-                mRowAlgorithm.bindRowViewIconToInfo(icon, info.apps.get(i));
-                icon.setVisibility(View.VISIBLE);
-            } else {
-                icon.setVisibility(View.INVISIBLE);
-            }
-        }
-        return row;
-    }
-
-    @Override
-    public Object[] getSections() {
-        ArrayList<Object> sections = new ArrayList<>();
-        int prevSectionId = -1;
-        for (AppsRow row : mAppRows) {
-            if (row.sectionId != prevSectionId) {
-                sections.add(row.sectionDescription.toUpperCase());
-                prevSectionId = row.sectionId;
-            }
-        }
-        return sections.toArray();
-    }
-
-    @Override
-    public int getPositionForSection(int sectionIndex) {
-        for (int i = 0; i < mAppRows.size(); i++) {
-            AppsRow row = mAppRows.get(i);
-            if (row.sectionId == sectionIndex) {
-                return i;
-            }
-        }
-        return 0;
-    }
-
-    @Override
-    public int getSectionForPosition(int position) {
-        return mAppRows.get(position).sectionId;
-    }
-}
-
-/**
- * The alphabetically sorted list of applications.
- */
-class AlphabeticalAppList {
-
-    /**
-     * Callbacks for when this list is modified.
-     */
-    public interface Callbacks {
-        public void onAppsUpdated();
-    }
-
-    private List<AppInfo> mApps;
-    private Callbacks mCb;
-
-    public AlphabeticalAppList(Callbacks cb) {
-        mCb = cb;
-    }
-
-    /**
-     * Returns the list of applications.
-     */
-    public List<AppInfo> getApps() {
-        return mApps;
-    }
-
-    /**
-     * Sets the current set of apps.
-     */
-    public void setApps(List<AppInfo> apps) {
-        Collections.sort(apps, LauncherModel.getAppNameComparator());
-        mApps = apps;
-        mCb.onAppsUpdated();
-    }
-
-    /**
-     * Adds new apps to the list.
-     */
-    public void addApps(List<AppInfo> apps) {
-        // We add it in place, in alphabetical order
-        Comparator<AppInfo> appNameComparator = LauncherModel.getAppNameComparator();
-        for (AppInfo info : apps) {
-            // This call will return the exact index of where the item is if >= 0, or the index
-            // where it should be inserted if < 0.
-            int index = Collections.binarySearch(mApps, info, appNameComparator);
-            if (index < 0) {
-                mApps.add(-(index + 1), info);
-            }
-        }
-        mCb.onAppsUpdated();
-    }
-
-    /**
-     * Updates existing apps in the list
-     */
-    public void updateApps(List<AppInfo> apps) {
-        Comparator<AppInfo> appNameComparator = LauncherModel.getAppNameComparator();
-        for (AppInfo info : apps) {
-            int index = mApps.indexOf(info);
-            if (index != -1) {
-                mApps.set(index, info);
-            } else {
-                index = Collections.binarySearch(mApps, info, appNameComparator);
-                if (index < 0) {
-                    mApps.add(-(index + 1), info);
-                }
-            }
-        }
-        mCb.onAppsUpdated();
-    }
-
-    /**
-     * Removes some apps from the list.
-     */
-    public void removeApps(List<AppInfo> apps) {
-        for (AppInfo info : apps) {
-            int removeIndex = findAppByComponent(mApps, info);
-            if (removeIndex != -1) {
-                mApps.remove(removeIndex);
-            }
-        }
-        mCb.onAppsUpdated();
-    }
-
-    /**
-     * Finds the index of an app given a target AppInfo.
-     */
-    private int findAppByComponent(List<AppInfo> apps, AppInfo targetInfo) {
-        ComponentName targetComponent = targetInfo.intent.getComponent();
-        int length = apps.size();
-        for (int i = 0; i < length; ++i) {
-            AppInfo info = apps.get(i);
-            if (info.user.equals(info.user)
-                    && info.intent.getComponent().equals(targetComponent)) {
-                return i;
-            }
-        }
-        return -1;
-    }
-
-}
-
-/**
  * The all apps list view container.
  */
 public class AppsContainerView extends FrameLayout implements DragSource, View.OnTouchListener,
-        View.OnLongClickListener, Insettable, AlphabeticalAppList.Callbacks {
+        View.OnLongClickListener, Insettable, TextWatcher, TextView.OnEditorActionListener,
+        LauncherTransitionable {
 
-    static final int GRID_LAYOUT = 0;
-    static final int LIST_LAYOUT = 1;
-    static final int USE_LAYOUT = LIST_LAYOUT;
+    private static final boolean ALLOW_SINGLE_APP_LAUNCH = true;
+
+    private static final int GRID_LAYOUT = 0;
+    private static final int LIST_LAYOUT = 1;
+    private static final int USE_LAYOUT = GRID_LAYOUT;
 
     private Launcher mLauncher;
-    private AppRowAlgorithm mAppRowsAlgorithm;
-    private AppsListAdapter mAdapter;
-    private AlphabeticalAppList mApps;
-    private ListView mList;
-    private int mAppsRowSize;
+    private AlphabeticalAppsList mApps;
+    private RecyclerView.Adapter mAdapter;
+    private RecyclerView.LayoutManager mLayoutManager;
+    private RecyclerView.ItemDecoration mItemDecoration;
+    private AppsContainerRecyclerView mAppsListView;
+    private EditText mSearchBar;
+    private int mNumAppsPerRow;
     private Point mLastTouchDownPos = new Point();
     private Rect mPadding = new Rect();
+    private int mContentMarginStart;
 
     public AppsContainerView(Context context) {
         this(context, null);
@@ -423,15 +78,22 @@
         DeviceProfile grid = app.getDynamicGrid().getDeviceProfile();
 
         mLauncher = (Launcher) context;
+        mApps = new AlphabeticalAppsList(context);
         if (USE_LAYOUT == GRID_LAYOUT) {
-            mAppRowsAlgorithm = new SectionedAppsAlgorithm();
-            mAppsRowSize = grid.allAppsRowsSize;
+            mNumAppsPerRow = grid.appsViewNumCols;
+            AppsGridAdapter adapter = new AppsGridAdapter(context, mApps, mNumAppsPerRow, this,
+                    mLauncher, this);
+            mLayoutManager = adapter.getLayoutManager(context);
+            mItemDecoration = adapter.getItemDecoration();
+            mAdapter = adapter;
+            mContentMarginStart = adapter.getContentMarginStart();
         } else if (USE_LAYOUT == LIST_LAYOUT) {
-            mAppRowsAlgorithm = new ListedAppsAlgorithm();
-            mAppsRowSize = 1;
+            mNumAppsPerRow = 1;
+            AppsListAdapter adapter = new AppsListAdapter(context, mApps, this, mLauncher, this);
+            mLayoutManager = adapter.getLayoutManager(context);
+            mAdapter = adapter;
         }
-        mAdapter = new AppsListAdapter(context, this, mLauncher, this);
-        mApps = new AlphabeticalAppList(this);
+        mApps.setAdapter(mAdapter);
     }
 
     /**
@@ -466,7 +128,7 @@
      * Scrolls this list view to the top.
      */
     public void scrollToTop() {
-        mList.scrollTo(0, 0);
+        mAppsListView.scrollToPosition(0);
     }
 
     /**
@@ -480,23 +142,37 @@
      * Returns the reveal view used for the launcher transitions.
      */
     public View getRevealView() {
-        return findViewById(R.id.all_apps_transition_overlay);
-    }
-
-    @Override
-    public void onAppsUpdated() {
-        List<AppsRow> rows = mAppRowsAlgorithm.computeAppRows(mApps.getApps(), mAppsRowSize);
-        mAdapter.setApps(rows, mAppsRowSize, mAppRowsAlgorithm);
+        return findViewById(R.id.apps_view_transition_overlay);
     }
 
     @Override
     protected void onFinishInflate() {
-        mList = (ListView) findViewById(R.id.apps_list);
-        mList.setFastScrollEnabled(true);
-        mList.setFastScrollAlwaysVisible(true);
-        mList.setItemsCanFocus(true);
-        mList.setAdapter(mAdapter);
-        mPadding.set(getPaddingLeft(), getPaddingTop(), getPaddingRight(), getPaddingBottom());
+        boolean isRtl = (getResources().getConfiguration().getLayoutDirection() ==
+                LAYOUT_DIRECTION_RTL);
+        if (USE_LAYOUT == GRID_LAYOUT) {
+            ((AppsGridAdapter) mAdapter).setRtl(isRtl);
+        }
+        mSearchBar = (EditText) findViewById(R.id.app_search_box);
+        mSearchBar.addTextChangedListener(this);
+        mSearchBar.setOnEditorActionListener(this);
+        mAppsListView = (AppsContainerRecyclerView) findViewById(R.id.apps_list_view);
+        mAppsListView.setApps(mApps);
+        mAppsListView.setNumAppsPerRow(mNumAppsPerRow);
+        mAppsListView.setLayoutManager(mLayoutManager);
+        mAppsListView.setAdapter(mAdapter);
+        mAppsListView.setHasFixedSize(true);
+        if (isRtl) {
+            mAppsListView.setPadding(mAppsListView.getPaddingLeft(), mAppsListView.getPaddingTop(),
+                    mAppsListView.getPaddingRight() + mContentMarginStart, mAppsListView.getPaddingBottom());
+        } else {
+            mAppsListView.setPadding(mAppsListView.getPaddingLeft() + mContentMarginStart, mAppsListView.getPaddingTop(),
+                    mAppsListView.getPaddingRight(), mAppsListView.getPaddingBottom());
+        }
+        if (mItemDecoration != null) {
+            mAppsListView.addItemDecoration(mItemDecoration);
+        }
+        mPadding.set(getPaddingLeft(), getPaddingTop(), getPaddingRight(),
+                getPaddingBottom());
     }
 
     @Override
@@ -574,7 +250,8 @@
     }
 
     @Override
-    public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete, boolean success) {
+    public void onDropCompleted(View target, DropTarget.DragObject d, boolean isFlingToDelete,
+            boolean success) {
         if (isFlingToDelete || !success || (target != mLauncher.getWorkspace() &&
                 !(target instanceof DeleteDropTarget) && !(target instanceof Folder))) {
             // Exit spring loaded mode if we have not successfully dropped or have not handled the
@@ -606,4 +283,83 @@
             d.deferDragViewCleanupPostAnimation = false;
         }
     }
+
+    @Override
+    public void beforeTextChanged(CharSequence s, int start, int count, int after) {
+        // Do nothing
+    }
+
+    @Override
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+        // Do nothing
+    }
+
+    @Override
+    public void afterTextChanged(final Editable s) {
+        if (s.toString().isEmpty()) {
+            mApps.setFilter(null);
+        } else {
+            final AlphabeticIndexCompat indexer = mApps.getIndexer();
+            final String filterText = s.toString().toLowerCase().replaceAll("\\s+", "");
+            mApps.setFilter(new AlphabeticalAppsList.Filter() {
+                @Override
+                public boolean retainApp(AppInfo info) {
+                    String title = info.title.toString();
+                    String sectionName = mApps.getSectionNameForApp(info);
+                    return sectionName.toLowerCase().contains(filterText) ||
+                            title.toLowerCase().replaceAll("\\s+", "").contains(filterText);
+                }
+            });
+        }
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        if (ALLOW_SINGLE_APP_LAUNCH && actionId == EditorInfo.IME_ACTION_DONE) {
+            List<AppInfo> appsWithoutSections = mApps.getAppsWithoutSectionBreaks();
+            List<AppInfo> apps = mApps.getApps();
+            if (appsWithoutSections.size() == 1) {
+                mSearchBar.clearFocus();
+                mAppsListView.getChildAt(apps.indexOf(appsWithoutSections.get(0))).performClick();
+                InputMethodManager imm = (InputMethodManager)
+                        getContext().getSystemService(Context.INPUT_METHOD_SERVICE);
+                imm.hideSoftInputFromWindow(getWindowToken(), 0);
+            }
+            return true;
+        }
+        return false;
+    }
+
+    @Override
+    public View getContent() {
+        return null;
+    }
+
+    @Override
+    public void onLauncherTransitionPrepare(Launcher l, boolean animated, boolean toWorkspace) {
+        if (!toWorkspace) {
+            // Disable the focus so that the search bar doesn't get focus
+            mSearchBar.setFocusableInTouchMode(false);
+        }
+    }
+
+    @Override
+    public void onLauncherTransitionStart(Launcher l, boolean animated, boolean toWorkspace) {
+        // Do nothing
+    }
+
+    @Override
+    public void onLauncherTransitionStep(Launcher l, float t) {
+        // Do nothing
+    }
+
+    @Override
+    public void onLauncherTransitionEnd(Launcher l, boolean animated, boolean toWorkspace) {
+        if (toWorkspace) {
+            // Clear the search bar
+            mSearchBar.setText("");
+        } else {
+            mSearchBar.setFocusableInTouchMode(true);
+        }
+    }
 }
diff --git a/src/com/android/launcher3/AppsGridAdapter.java b/src/com/android/launcher3/AppsGridAdapter.java
new file mode 100644
index 0000000..6727e4f
--- /dev/null
+++ b/src/com/android/launcher3/AppsGridAdapter.java
@@ -0,0 +1,206 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.support.v7.widget.GridLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
+
+
+/**
+ * The grid view adapter of all the apps.
+ */
+class AppsGridAdapter extends RecyclerView.Adapter<AppsGridAdapter.ViewHolder> {
+
+    public static final String TAG = "AppsGridAdapter";
+
+    private static final int SECTION_BREAK_VIEW_TYPE = 0;
+    private static final int ICON_VIEW_TYPE = 1;
+
+    /**
+     * ViewHolder for each icon.
+     */
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+        public View mContent;
+        public boolean mIsSectionRow;
+
+        public ViewHolder(View v, boolean isSectionRow) {
+            super(v);
+            mContent = v;
+            mIsSectionRow = isSectionRow;
+        }
+    }
+
+    /**
+     * Helper class to size the grid items.
+     */
+    public class GridSpanSizer extends GridLayoutManager.SpanSizeLookup {
+        @Override
+        public int getSpanSize(int position) {
+            AppInfo info = mApps.getApps().get(position);
+            if (info == AlphabeticalAppsList.SECTION_BREAK_INFO) {
+                return mAppsPerRow;
+            } else {
+                return 1;
+            }
+        }
+    }
+
+    /**
+     * Helper class to draw the section headers
+     */
+    public class GridItemDecoration extends RecyclerView.ItemDecoration {
+
+        @Override
+        public void onDraw(Canvas c, RecyclerView parent, RecyclerView.State state) {
+            AlphabeticIndexCompat indexer = mApps.getIndexer();
+            for (int i = 0; i < parent.getChildCount(); i++) {
+                View child = parent.getChildAt(i);
+                ViewHolder holder = (ViewHolder) parent.getChildViewHolder(child);
+                if (holder != null) {
+                    GridLayoutManager.LayoutParams lp = (GridLayoutManager.LayoutParams)
+                            child.getLayoutParams();
+                    if (!holder.mIsSectionRow && !lp.isItemRemoved()) {
+                        if (mApps.getApps().get(holder.getPosition() - 1) ==
+                                AlphabeticalAppsList.SECTION_BREAK_INFO) {
+                            // Draw at the parent
+                            AppInfo info = mApps.getApps().get(holder.getPosition());
+                            String section = mApps.getSectionNameForApp(info);
+                            mSectionTextPaint.getTextBounds(section, 0, section.length(),
+                                    mTmpBounds);
+                            if (mIsRtl) {
+                                c.drawText(section, parent.getWidth() - mStartMargin +
+                                                (mStartMargin - mTmpBounds.width()) / 2,
+                                        child.getTop() + (2 * child.getPaddingTop()) +
+                                                mTmpBounds.height(), mSectionTextPaint);
+                            } else {
+                                c.drawText(section, (mStartMargin - mTmpBounds.width()) / 2,
+                                    child.getTop() + (2 * child.getPaddingTop()) +
+                                            mTmpBounds.height(), mSectionTextPaint);
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        @Override
+        public void getItemOffsets(Rect outRect, View view, RecyclerView parent,
+                RecyclerView.State state) {
+            // Do nothing
+        }
+    }
+
+    private LayoutInflater mLayoutInflater;
+    private AlphabeticalAppsList mApps;
+    private GridSpanSizer mGridSizer;
+    private GridItemDecoration mItemDecoration;
+    private View.OnTouchListener mTouchListener;
+    private View.OnClickListener mIconClickListener;
+    private View.OnLongClickListener mIconLongClickListener;
+    private int mAppsPerRow;
+    private boolean mIsRtl;
+
+    // Section drawing
+    private int mStartMargin;
+    private Paint mSectionTextPaint;
+    private Rect mTmpBounds = new Rect();
+
+
+    public AppsGridAdapter(Context context, AlphabeticalAppsList apps, int appsPerRow,
+            View.OnTouchListener touchListener, View.OnClickListener iconClickListener,
+            View.OnLongClickListener iconLongClickListener) {
+        Resources res = context.getResources();
+        mApps = apps;
+        mAppsPerRow = appsPerRow;
+        mGridSizer = new GridSpanSizer();
+        mItemDecoration = new GridItemDecoration();
+        mLayoutInflater = LayoutInflater.from(context);
+        mTouchListener = touchListener;
+        mIconClickListener = iconClickListener;
+        mIconLongClickListener = iconLongClickListener;
+        mStartMargin = res.getDimensionPixelSize(R.dimen.apps_grid_view_start_margin);
+        mSectionTextPaint = new Paint();
+        mSectionTextPaint.setTextSize(res.getDimensionPixelSize(
+                R.dimen.apps_view_section_text_size));
+        mSectionTextPaint.setColor(res.getColor(R.color.apps_view_section_text_color));
+        mSectionTextPaint.setAntiAlias(true);
+    }
+
+    /**
+     * Sets whether we are in RTL mode.
+     */
+    public void setRtl(boolean rtl) {
+        mIsRtl = rtl;
+    }
+
+    /**
+     * Returns the grid layout manager.
+     */
+    public GridLayoutManager getLayoutManager(Context context) {
+        GridLayoutManager layoutMgr = new GridLayoutManager(context, mAppsPerRow,
+                GridLayoutManager.VERTICAL, false);
+        layoutMgr.setSpanSizeLookup(mGridSizer);
+        return layoutMgr;
+    }
+
+    /**
+     * Returns the item decoration for the recycler view.
+     */
+    public RecyclerView.ItemDecoration getItemDecoration() {
+        return mItemDecoration;
+    }
+
+    /**
+     * Returns the left padding for the recycler view.
+     */
+    public int getContentMarginStart() {
+        return mStartMargin;
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        switch (viewType) {
+            case SECTION_BREAK_VIEW_TYPE:
+                return new ViewHolder(new View(parent.getContext()), true);
+            case ICON_VIEW_TYPE:
+                BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
+                        R.layout.apps_grid_row_icon_view, parent, false);
+                icon.setOnTouchListener(mTouchListener);
+                icon.setOnClickListener(mIconClickListener);
+                icon.setOnLongClickListener(mIconLongClickListener);
+                icon.setFocusable(true);
+                return new ViewHolder(icon, false);
+            default:
+                throw new RuntimeException("Unexpected view type");
+        }
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        AppInfo info = mApps.getApps().get(position);
+        if (info != AlphabeticalAppsList.SECTION_BREAK_INFO) {
+            BubbleTextView icon = (BubbleTextView) holder.mContent;
+            icon.applyFromApplicationInfo(info);
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return mApps.getApps().size();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (mApps.getApps().get(position) == AlphabeticalAppsList.SECTION_BREAK_INFO) {
+            return SECTION_BREAK_VIEW_TYPE;
+        }
+        return ICON_VIEW_TYPE;
+    }
+}
diff --git a/src/com/android/launcher3/AppsListAdapter.java b/src/com/android/launcher3/AppsListAdapter.java
new file mode 100644
index 0000000..8ac381e
--- /dev/null
+++ b/src/com/android/launcher3/AppsListAdapter.java
@@ -0,0 +1,119 @@
+package com.android.launcher3;
+
+import android.content.Context;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import com.android.launcher3.compat.AlphabeticIndexCompat;
+
+/**
+ * The linear list view adapter for all the apps.
+ */
+class AppsListAdapter extends RecyclerView.Adapter<AppsListAdapter.ViewHolder> {
+
+    /**
+     * ViewHolder for each row.
+     */
+    public static class ViewHolder extends RecyclerView.ViewHolder {
+        public View mContent;
+
+        public ViewHolder(View v) {
+            super(v);
+            mContent = v;
+        }
+    }
+
+    private static final int SECTION_BREAK_VIEW_TYPE = 0;
+    private static final int ICON_VIEW_TYPE = 1;
+
+    private LayoutInflater mLayoutInflater;
+    private AlphabeticalAppsList mApps;
+    private View.OnTouchListener mTouchListener;
+    private View.OnClickListener mIconClickListener;
+    private View.OnLongClickListener mIconLongClickListener;
+
+    public AppsListAdapter(Context context, AlphabeticalAppsList apps,
+            View.OnTouchListener touchListener, View.OnClickListener iconClickListener,
+            View.OnLongClickListener iconLongClickListener) {
+        mApps = apps;
+        mLayoutInflater = LayoutInflater.from(context);
+        mTouchListener = touchListener;
+        mIconClickListener = iconClickListener;
+        mIconLongClickListener = iconLongClickListener;
+    }
+
+    public RecyclerView.LayoutManager getLayoutManager(Context context) {
+        return new LinearLayoutManager(context);
+    }
+
+    @Override
+    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
+        switch (viewType) {
+            case SECTION_BREAK_VIEW_TYPE:
+                return new ViewHolder(new View(parent.getContext()));
+            case ICON_VIEW_TYPE:
+                // Inflate the row and all the icon children necessary
+                ViewGroup row = (ViewGroup) mLayoutInflater.inflate(R.layout.apps_list_row_view,
+                        parent, false);
+                BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate(
+                        R.layout.apps_list_row_icon_view, row, false);
+                LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(0,
+                        ViewGroup.LayoutParams.WRAP_CONTENT, 1);
+                lp.gravity = Gravity.CENTER_VERTICAL;
+                icon.setLayoutParams(lp);
+                icon.setOnTouchListener(mTouchListener);
+                icon.setOnClickListener(mIconClickListener);
+                icon.setOnLongClickListener(mIconLongClickListener);
+                icon.setFocusable(true);
+                row.addView(icon);
+                return new ViewHolder(row);
+            default:
+                throw new RuntimeException("Unexpected view type");
+        }
+    }
+
+    @Override
+    public void onBindViewHolder(ViewHolder holder, int position) {
+        AppInfo info = mApps.getApps().get(position);
+        if (info != AlphabeticalAppsList.SECTION_BREAK_INFO) {
+            ViewGroup content = (ViewGroup) holder.mContent;
+            String sectionDescription = mApps.getSectionNameForApp(info);
+
+            // Bind the section header
+            boolean showSectionHeader = true;
+            if (position > 0) {
+                AppInfo prevInfo = mApps.getApps().get(position - 1);
+                showSectionHeader = (prevInfo == AlphabeticalAppsList.SECTION_BREAK_INFO);
+            }
+            TextView tv = (TextView) content.findViewById(R.id.section);
+            if (showSectionHeader) {
+                tv.setText(sectionDescription);
+                tv.setVisibility(View.VISIBLE);
+            } else {
+                tv.setVisibility(View.INVISIBLE);
+            }
+
+            // Bind the icon
+            BubbleTextView icon = (BubbleTextView) content.getChildAt(1);
+            icon.applyFromApplicationInfo(info);
+        }
+    }
+
+    @Override
+    public int getItemCount() {
+        return mApps.getApps().size();
+    }
+
+    @Override
+    public int getItemViewType(int position) {
+        if (mApps.getApps().get(position) == AlphabeticalAppsList.SECTION_BREAK_INFO) {
+            return SECTION_BREAK_VIEW_TYPE;
+        }
+        return ICON_VIEW_TYPE;
+    }
+}
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 5ea84ae..fabae57 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -63,6 +63,7 @@
 
     private float mSlop;
 
+    private final boolean mDeferShadowGenerationOnTouch;
     private final boolean mCustomShadowsEnabled;
     private final boolean mLayoutHorizontal;
     private final int mIconSize;
@@ -96,6 +97,8 @@
                 grid.iconDrawablePaddingPx);
         mTextSize = a.getDimensionPixelSize(R.styleable.BubbleTextView_textSizeOverride,
                 grid.allAppsIconTextSizePx);
+        mDeferShadowGenerationOnTouch =
+                a.getBoolean(R.styleable.BubbleTextView_deferShadowGeneration, false);
         a.recycle();
 
         if (mCustomShadowsEnabled) {
@@ -218,7 +221,7 @@
                 // So that the pressed outline is visible immediately on setStayPressed(),
                 // we pre-create it on ACTION_DOWN (it takes a small but perceptible amount of time
                 // to create it)
-                if (mPressedBackground == null) {
+                if (!mDeferShadowGenerationOnTouch && mPressedBackground == null) {
                     mPressedBackground = mOutlineHelper.createMediumDropShadow(this);
                 }
 
@@ -247,6 +250,10 @@
         mStayPressed = stayPressed;
         if (!stayPressed) {
             mPressedBackground = null;
+        } else {
+            if (mPressedBackground == null) {
+                mPressedBackground = mOutlineHelper.createMediumDropShadow(this);
+            }
         }
 
         // Only show the shadow effect when persistent pressed state is set.
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index b5bb55c..ddd3002 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -122,8 +122,7 @@
     int hotseatAllAppsRank;
     int allAppsNumRows;
     int allAppsNumCols;
-    // TODO(winsonc): to be used with the grid layout
-    int allAppsRowsSize;
+    int appsViewNumCols;
     int searchBarSpaceWidthPx;
     int searchBarSpaceHeightPx;
     int pageIndicatorHeightPx;
@@ -365,7 +364,7 @@
         }
     }
 
-    private void updateIconSize(float scale, int drawablePadding, Resources resources,
+    private void updateIconSize(float scale, int drawablePadding, Resources res,
                                 DisplayMetrics dm) {
         iconSizePx = (int) (DynamicGrid.pxFromDp(iconSize, dm) * scale);
         iconTextSizePx = (int) (DynamicGrid.pxFromSp(iconTextSize, dm) * scale);
@@ -374,9 +373,9 @@
 
         // Search Bar
         searchBarSpaceWidthPx = Math.min(widthPx,
-                resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
+                res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_max_width));
         searchBarSpaceHeightPx = getSearchBarTopOffset()
-                + resources.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
+                + res.getDimensionPixelSize(R.dimen.dynamic_grid_search_bar_height);
 
         // Calculate the actual text height
         Paint textPaint = new Paint();
@@ -384,7 +383,7 @@
         FontMetrics fm = textPaint.getFontMetrics();
         cellWidthPx = iconSizePx;
         cellHeightPx = iconSizePx + iconDrawablePaddingPx + (int) Math.ceil(fm.bottom - fm.top);
-        final float scaleDps = resources.getDimensionPixelSize(R.dimen.dragViewScale);
+        final float scaleDps = res.getDimensionPixelSize(R.dimen.dragViewScale);
         dragViewScale = (iconSizePx + scaleDps) / iconSizePx;
 
         // Hotseat
@@ -402,11 +401,11 @@
         allAppsCellWidthPx = allAppsIconSizePx;
         allAppsCellHeightPx = allAppsIconSizePx + drawablePadding + iconTextSizePx;
         int maxLongEdgeCellCount =
-                resources.getInteger(R.integer.config_dynamic_grid_max_long_edge_cell_count);
+                res.getInteger(R.integer.config_dynamic_grid_max_long_edge_cell_count);
         int maxShortEdgeCellCount =
-                resources.getInteger(R.integer.config_dynamic_grid_max_short_edge_cell_count);
+                res.getInteger(R.integer.config_dynamic_grid_max_short_edge_cell_count);
         int minEdgeCellCount =
-                resources.getInteger(R.integer.config_dynamic_grid_min_edge_cell_count);
+                res.getInteger(R.integer.config_dynamic_grid_min_edge_cell_count);
         int maxRows = (isLandscape ? maxShortEdgeCellCount : maxLongEdgeCellCount);
         int maxCols = (isLandscape ? maxLongEdgeCellCount : maxShortEdgeCellCount);
 
@@ -417,10 +416,17 @@
             allAppsNumRows = (availableHeightPx - pageIndicatorHeightPx) /
                     (allAppsCellHeightPx + allAppsCellPaddingPx);
             allAppsNumRows = Math.max(minEdgeCellCount, Math.min(maxRows, allAppsNumRows));
-            allAppsNumCols = (availableWidthPx) /
-                    (allAppsCellWidthPx + allAppsCellPaddingPx);
+            allAppsNumCols = (availableWidthPx) / (allAppsCellWidthPx + allAppsCellPaddingPx);
             allAppsNumCols = Math.max(minEdgeCellCount, Math.min(maxCols, allAppsNumCols));
         }
+
+        int appsContainerViewPx = res.getDimensionPixelSize(R.dimen.apps_container_width);
+        int appsViewLeftMarginPx =
+                res.getDimensionPixelSize(R.dimen.apps_grid_view_start_margin);
+        int availableAppsWidthPx = (appsContainerViewPx > 0) ? appsContainerViewPx :
+                availableWidthPx;
+        appsViewNumCols = (availableAppsWidthPx - appsViewLeftMarginPx) /
+                (allAppsCellWidthPx + allAppsCellPaddingPx);
     }
 
     void updateFromConfiguration(Context context, Resources resources, int wPx, int hPx,
diff --git a/src/com/android/launcher3/compat/AlphabeticIndexCompat.java b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
new file mode 100644
index 0000000..602a845
--- /dev/null
+++ b/src/com/android/launcher3/compat/AlphabeticIndexCompat.java
@@ -0,0 +1,131 @@
+package com.android.launcher3.compat;
+
+import android.content.Context;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Method;
+import java.util.Locale;
+
+/**
+ * Fallback class to support Alphabetic indexing if not supported by the framework.
+ * TODO(winsonc): disable for non-english locales
+ */
+class BaseAlphabeticIndex {
+
+    private static final String BUCKETS = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ-";
+    private static final int UNKNOWN_BUCKET_INDEX = BUCKETS.length() - 1;
+
+    public BaseAlphabeticIndex() {}
+
+    /**
+     * Sets the max number of the label buckets in this index.
+     */
+    public void setMaxLabelCount(int count) {
+        // Not currently supported
+    }
+
+    /**
+     * Returns the index of the bucket in which the given string should appear.
+     */
+    public int getBucketIndex(String s) {
+        if (s.isEmpty()) {
+            return UNKNOWN_BUCKET_INDEX;
+        }
+        int index = BUCKETS.indexOf(s.substring(0, 1).toUpperCase());
+        if (index != -1) {
+            return index;
+        }
+        return UNKNOWN_BUCKET_INDEX;
+    }
+
+    /**
+     * Returns the label for the bucket at the given index (as returned by getBucketIndex).
+     */
+    public String getBucketLabel(int index) {
+        return BUCKETS.substring(index, index + 1);
+    }
+}
+
+/**
+ * Reflected libcore.icu.AlphabeticIndex implementation, falls back to the base alphabetic index.
+ */
+public class AlphabeticIndexCompat extends BaseAlphabeticIndex {
+
+    private Object mAlphabeticIndex;
+    private Method mAddLabelsMethod;
+    private Method mSetMaxLabelCountMethod;
+    private Method mGetBucketIndexMethod;
+    private Method mGetBucketLabelMethod;
+    private boolean mHasValidAlphabeticIndex;
+
+    public AlphabeticIndexCompat(Context context) {
+        super();
+        try {
+            Locale curLocale = context.getResources().getConfiguration().locale;
+            Class clazz = Class.forName("libcore.icu.AlphabeticIndex");
+            Constructor ctor = clazz.getConstructor(Locale.class);
+            mAddLabelsMethod = clazz.getDeclaredMethod("addLabels", Locale.class);
+            mSetMaxLabelCountMethod = clazz.getDeclaredMethod("setMaxLabelCount", int.class);
+            mGetBucketIndexMethod = clazz.getDeclaredMethod("getBucketIndex", String.class);
+            mGetBucketLabelMethod = clazz.getDeclaredMethod("getBucketLabel", int.class);
+            mAlphabeticIndex = ctor.newInstance(curLocale);
+            try {
+                // Ensure we always have some base English locale buckets
+                if (!curLocale.getLanguage().equals(new Locale("en").getLanguage())) {
+                    mAddLabelsMethod.invoke(mAlphabeticIndex, Locale.ENGLISH);
+                }
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+            mHasValidAlphabeticIndex = true;
+        } catch (Exception e) {
+            mHasValidAlphabeticIndex = false;
+        }
+    }
+
+    /**
+     * Sets the max number of the label buckets in this index.
+     * (ICU 51 default is 99)
+     */
+    public void setMaxLabelCount(int count) {
+        if (mHasValidAlphabeticIndex) {
+            try {
+                mSetMaxLabelCountMethod.invoke(mAlphabeticIndex, count);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        } else {
+            super.setMaxLabelCount(count);
+        }
+    }
+
+    /**
+     * Returns the index of the bucket in which {@param s} should appear.
+     * Function is synchronized because underlying routine walks an iterator
+     * whose state is maintained inside the index object.
+     */
+    public int getBucketIndex(String s) {
+        if (mHasValidAlphabeticIndex) {
+            try {
+                return (Integer) mGetBucketIndexMethod.invoke(mAlphabeticIndex, s);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return super.getBucketIndex(s);
+    }
+
+    /**
+     * Returns the label for the bucket at the given index (as returned by getBucketIndex).
+     */
+    public String getBucketLabel(int index) {
+        if (mHasValidAlphabeticIndex) {
+            try {
+                return (String) mGetBucketLabelMethod.invoke(mAlphabeticIndex, index);
+            } catch (Exception e) {
+                e.printStackTrace();
+            }
+        }
+        return super.getBucketLabel(index);
+    }
+}
