diff --git a/src/com/android/launcher3/AutoScrollHelper.java b/src/com/android/launcher3/AutoScrollHelper.java
deleted file mode 100644
index e41107c..0000000
--- a/src/com/android/launcher3/AutoScrollHelper.java
+++ /dev/null
@@ -1,867 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.launcher3;
-
-import android.content.res.Resources;
-import android.os.SystemClock;
-import android.support.v4.view.MotionEventCompat;
-import android.support.v4.view.ViewCompat;
-import android.util.DisplayMetrics;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.AnimationUtils;
-import android.view.animation.Interpolator;
-
-/**
- * AutoScrollHelper is a utility class for adding automatic edge-triggered
- * scrolling to Views.
- * <p>
- * <b>Note:</b> Implementing classes are responsible for overriding the
- * {@link #scrollTargetBy}, {@link #canTargetScrollHorizontally}, and
- * {@link #canTargetScrollVertically} methods. See
- * {@link ListViewAutoScrollHelper} for a {@link android.widget.ListView}
- * -specific implementation.
- * <p>
- * <h1>Activation</h1> Automatic scrolling starts when the user touches within
- * an activation area. By default, activation areas are defined as the top,
- * left, right, and bottom 20% of the host view's total area. Touching within
- * the top activation area scrolls up, left scrolls to the left, and so on.
- * <p>
- * As the user touches closer to the extreme edge of the activation area,
- * scrolling accelerates up to a maximum velocity. When using the default edge
- * type, {@link #EDGE_TYPE_INSIDE_EXTEND}, moving outside of the view bounds
- * will scroll at the maximum velocity.
- * <p>
- * The following activation properties may be configured:
- * <ul>
- * <li>Delay after entering activation area before auto-scrolling begins, see
- * {@link #setActivationDelay}. Default value is
- * {@link ViewConfiguration#getTapTimeout()} to avoid conflicting with taps.
- * <li>Location of activation areas, see {@link #setEdgeType}. Default value is
- * {@link #EDGE_TYPE_INSIDE_EXTEND}.
- * <li>Size of activation areas relative to view size, see
- * {@link #setRelativeEdges}. Default value is 20% for both vertical and
- * horizontal edges.
- * <li>Maximum size used to constrain relative size, see
- * {@link #setMaximumEdges}. Default value is {@link #NO_MAX}.
- * </ul>
- * <h1>Scrolling</h1> When automatic scrolling is active, the helper will
- * repeatedly call {@link #scrollTargetBy} to apply new scrolling offsets.
- * <p>
- * The following scrolling properties may be configured:
- * <ul>
- * <li>Acceleration ramp-up duration, see {@link #setRampUpDuration}. Default
- * value is 500 milliseconds.
- * <li>Acceleration ramp-down duration, see {@link #setRampDownDuration}.
- * Default value is 500 milliseconds.
- * <li>Target velocity relative to view size, see {@link #setRelativeVelocity}.
- * Default value is 100% per second for both vertical and horizontal.
- * <li>Minimum velocity used to constrain relative velocity, see
- * {@link #setMinimumVelocity}. When set, scrolling will accelerate to the
- * larger of either this value or the relative target value. Default value is
- * approximately 5 centimeters or 315 dips per second.
- * <li>Maximum velocity used to constrain relative velocity, see
- * {@link #setMaximumVelocity}. Default value is approximately 25 centimeters or
- * 1575 dips per second.
- * </ul>
- */
-public abstract class AutoScrollHelper implements View.OnTouchListener {
-    /**
-     * Constant passed to {@link #setRelativeEdges} or
-     * {@link #setRelativeVelocity}. Using this value ensures that the computed
-     * relative value is ignored and the absolute maximum value is always used.
-     */
-    public static final float RELATIVE_UNSPECIFIED = 0;
-
-    /**
-     * Constant passed to {@link #setMaximumEdges}, {@link #setMaximumVelocity},
-     * or {@link #setMinimumVelocity}. Using this value ensures that the
-     * computed relative value is always used without constraining to a
-     * particular minimum or maximum value.
-     */
-    public static final float NO_MAX = Float.MAX_VALUE;
-
-    /**
-     * Constant passed to {@link #setMaximumEdges}, or
-     * {@link #setMaximumVelocity}, or {@link #setMinimumVelocity}. Using this
-     * value ensures that the computed relative value is always used without
-     * constraining to a particular minimum or maximum value.
-     */
-    public static final float NO_MIN = 0;
-
-    /**
-     * Edge type that specifies an activation area starting at the view bounds
-     * and extending inward. Moving outside the view bounds will stop scrolling.
-     *
-     * @see #setEdgeType
-     */
-    public static final int EDGE_TYPE_INSIDE = 0;
-
-    /**
-     * Edge type that specifies an activation area starting at the view bounds
-     * and extending inward. After activation begins, moving outside the view
-     * bounds will continue scrolling.
-     *
-     * @see #setEdgeType
-     */
-    public static final int EDGE_TYPE_INSIDE_EXTEND = 1;
-
-    /**
-     * Edge type that specifies an activation area starting at the view bounds
-     * and extending outward. Moving inside the view bounds will stop scrolling.
-     *
-     * @see #setEdgeType
-     */
-    public static final int EDGE_TYPE_OUTSIDE = 2;
-
-    private static final int HORIZONTAL = 0;
-    private static final int VERTICAL = 1;
-
-    /** Scroller used to control acceleration toward maximum velocity. */
-    private final ClampedScroller mScroller = new ClampedScroller();
-
-    /** Interpolator used to scale velocity with touch position. */
-    private final Interpolator mEdgeInterpolator = new AccelerateInterpolator();
-
-    /** The view to auto-scroll. Might not be the source of touch events. */
-    private final View mTarget;
-
-    /** Runnable used to animate scrolling. */
-    private Runnable mRunnable;
-
-    /** Edge insets used to activate auto-scrolling. */
-    private float[] mRelativeEdges = new float[] { RELATIVE_UNSPECIFIED, RELATIVE_UNSPECIFIED };
-
-    /** Clamping values for edge insets used to activate auto-scrolling. */
-    private float[] mMaximumEdges = new float[] { NO_MAX, NO_MAX };
-
-    /** The type of edge being used. */
-    private int mEdgeType;
-
-    /** Delay after entering an activation edge before auto-scrolling begins. */
-    private int mActivationDelay;
-
-    /** Relative scrolling velocity at maximum edge distance. */
-    private float[] mRelativeVelocity = new float[] { RELATIVE_UNSPECIFIED, RELATIVE_UNSPECIFIED };
-
-    /** Clamping values used for scrolling velocity. */
-    private float[] mMinimumVelocity = new float[] { NO_MIN, NO_MIN };
-
-    /** Clamping values used for scrolling velocity. */
-    private float[] mMaximumVelocity = new float[] { NO_MAX, NO_MAX };
-
-    /** Whether to start activation immediately. */
-    private boolean mAlreadyDelayed;
-
-    /** Whether to reset the scroller start time on the next animation. */
-    private boolean mNeedsReset;
-
-    /** Whether to send a cancel motion event to the target view. */
-    private boolean mNeedsCancel;
-
-    /** Whether the auto-scroller is actively scrolling. */
-    private boolean mAnimating;
-
-    /** Whether the auto-scroller is enabled. */
-    private boolean mEnabled;
-
-    /** Whether the auto-scroller consumes events when scrolling. */
-    private boolean mExclusive;
-
-    // Default values.
-    private static final int DEFAULT_EDGE_TYPE = EDGE_TYPE_INSIDE_EXTEND;
-    private static final int DEFAULT_MINIMUM_VELOCITY_DIPS = 315;
-    private static final int DEFAULT_MAXIMUM_VELOCITY_DIPS = 1575;
-    private static final float DEFAULT_MAXIMUM_EDGE = NO_MAX;
-    private static final float DEFAULT_RELATIVE_EDGE = 0.2f;
-    private static final float DEFAULT_RELATIVE_VELOCITY = 1f;
-    private static final int DEFAULT_ACTIVATION_DELAY = ViewConfiguration.getTapTimeout();
-    private static final int DEFAULT_RAMP_UP_DURATION = 500;
-    private static final int DEFAULT_RAMP_DOWN_DURATION = 500;
-
-    /**
-     * Creates a new helper for scrolling the specified target view.
-     * <p>
-     * The resulting helper may be configured by chaining setter calls and
-     * should be set as a touch listener on the target view.
-     * <p>
-     * By default, the helper is disabled and will not respond to touch events
-     * until it is enabled using {@link #setEnabled}.
-     *
-     * @param target The view to automatically scroll.
-     */
-    public AutoScrollHelper(View target) {
-        mTarget = target;
-
-        final DisplayMetrics metrics = Resources.getSystem().getDisplayMetrics();
-        final int maxVelocity = (int) (DEFAULT_MAXIMUM_VELOCITY_DIPS * metrics.density + 0.5f);
-        final int minVelocity = (int) (DEFAULT_MINIMUM_VELOCITY_DIPS * metrics.density + 0.5f);
-        setMaximumVelocity(maxVelocity, maxVelocity);
-        setMinimumVelocity(minVelocity, minVelocity);
-
-        setEdgeType(DEFAULT_EDGE_TYPE);
-        setMaximumEdges(DEFAULT_MAXIMUM_EDGE, DEFAULT_MAXIMUM_EDGE);
-        setRelativeEdges(DEFAULT_RELATIVE_EDGE, DEFAULT_RELATIVE_EDGE);
-        setRelativeVelocity(DEFAULT_RELATIVE_VELOCITY, DEFAULT_RELATIVE_VELOCITY);
-        setActivationDelay(DEFAULT_ACTIVATION_DELAY);
-        setRampUpDuration(DEFAULT_RAMP_UP_DURATION);
-        setRampDownDuration(DEFAULT_RAMP_DOWN_DURATION);
-    }
-
-    /**
-     * Sets whether the scroll helper is enabled and should respond to touch
-     * events.
-     *
-     * @param enabled Whether the scroll helper is enabled.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setEnabled(boolean enabled) {
-        if (mEnabled && !enabled) {
-            requestStop();
-        }
-
-        mEnabled = enabled;
-        return this;
-    }
-
-    /**
-     * @return True if this helper is enabled and responding to touch events.
-     */
-    public boolean isEnabled() {
-        return mEnabled;
-    }
-
-    /**
-     * Enables or disables exclusive handling of touch events during scrolling.
-     * By default, exclusive handling is disabled and the target view receives
-     * all touch events.
-     * <p>
-     * When enabled, {@link #onTouch} will return true if the helper is
-     * currently scrolling and false otherwise.
-     *
-     * @param exclusive True to exclusively handle touch events during scrolling,
-     *            false to allow the target view to receive all touch events.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setExclusive(boolean exclusive) {
-        mExclusive = exclusive;
-        return this;
-    }
-
-    /**
-     * Indicates whether the scroll helper handles touch events exclusively
-     * during scrolling.
-     *
-     * @return True if exclusive handling of touch events during scrolling is
-     *         enabled, false otherwise.
-     * @see #setExclusive(boolean)
-     */
-    public boolean isExclusive() {
-        return mExclusive;
-    }
-
-    /**
-     * Sets the absolute maximum scrolling velocity.
-     * <p>
-     * If relative velocity is not specified, scrolling will always reach the
-     * same maximum velocity. If both relative and maximum velocities are
-     * specified, the maximum velocity will be used to clamp the calculated
-     * relative velocity.
-     *
-     * @param horizontalMax The maximum horizontal scrolling velocity, or
-     *            {@link #NO_MAX} to leave the relative value unconstrained.
-     * @param verticalMax The maximum vertical scrolling velocity, or
-     *            {@link #NO_MAX} to leave the relative value unconstrained.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setMaximumVelocity(float horizontalMax, float verticalMax) {
-        mMaximumVelocity[HORIZONTAL] = horizontalMax / 1000f;
-        mMaximumVelocity[VERTICAL] = verticalMax / 1000f;
-        return this;
-    }
-
-    /**
-     * Sets the absolute minimum scrolling velocity.
-     * <p>
-     * If both relative and minimum velocities are specified, the minimum
-     * velocity will be used to clamp the calculated relative velocity.
-     *
-     * @param horizontalMin The minimum horizontal scrolling velocity, or
-     *            {@link #NO_MIN} to leave the relative value unconstrained.
-     * @param verticalMin The minimum vertical scrolling velocity, or
-     *            {@link #NO_MIN} to leave the relative value unconstrained.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setMinimumVelocity(float horizontalMin, float verticalMin) {
-        mMinimumVelocity[HORIZONTAL] = horizontalMin / 1000f;
-        mMinimumVelocity[VERTICAL] = verticalMin / 1000f;
-        return this;
-    }
-
-    /**
-     * Sets the target scrolling velocity relative to the host view's
-     * dimensions.
-     * <p>
-     * If both relative and maximum velocities are specified, the maximum
-     * velocity will be used to clamp the calculated relative velocity.
-     *
-     * @param horizontal The target horizontal velocity as a fraction of the
-     *            host view width per second, or {@link #RELATIVE_UNSPECIFIED}
-     *            to ignore.
-     * @param vertical The target vertical velocity as a fraction of the host
-     *            view height per second, or {@link #RELATIVE_UNSPECIFIED} to
-     *            ignore.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setRelativeVelocity(float horizontal, float vertical) {
-        mRelativeVelocity[HORIZONTAL] = horizontal / 1000f;
-        mRelativeVelocity[VERTICAL] = vertical / 1000f;
-        return this;
-    }
-
-    /**
-     * Sets the activation edge type, one of:
-     * <ul>
-     * <li>{@link #EDGE_TYPE_INSIDE} for edges that respond to touches inside
-     * the bounds of the host view. If touch moves outside the bounds, scrolling
-     * will stop.
-     * <li>{@link #EDGE_TYPE_INSIDE_EXTEND} for inside edges that continued to
-     * scroll when touch moves outside the bounds of the host view.
-     * <li>{@link #EDGE_TYPE_OUTSIDE} for edges that only respond to touches
-     * that move outside the bounds of the host view.
-     * </ul>
-     *
-     * @param type The type of edge to use.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setEdgeType(int type) {
-        mEdgeType = type;
-        return this;
-    }
-
-    /**
-     * Sets the activation edge size relative to the host view's dimensions.
-     * <p>
-     * If both relative and maximum edges are specified, the maximum edge will
-     * be used to constrain the calculated relative edge size.
-     *
-     * @param horizontal The horizontal edge size as a fraction of the host view
-     *            width, or {@link #RELATIVE_UNSPECIFIED} to always use the
-     *            maximum value.
-     * @param vertical The vertical edge size as a fraction of the host view
-     *            height, or {@link #RELATIVE_UNSPECIFIED} to always use the
-     *            maximum value.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setRelativeEdges(float horizontal, float vertical) {
-        mRelativeEdges[HORIZONTAL] = horizontal;
-        mRelativeEdges[VERTICAL] = vertical;
-        return this;
-    }
-
-    /**
-     * Sets the absolute maximum edge size.
-     * <p>
-     * If relative edge size is not specified, activation edges will always be
-     * the maximum edge size. If both relative and maximum edges are specified,
-     * the maximum edge will be used to constrain the calculated relative edge
-     * size.
-     *
-     * @param horizontalMax The maximum horizontal edge size in pixels, or
-     *            {@link #NO_MAX} to use the unconstrained calculated relative
-     *            value.
-     * @param verticalMax The maximum vertical edge size in pixels, or
-     *            {@link #NO_MAX} to use the unconstrained calculated relative
-     *            value.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setMaximumEdges(float horizontalMax, float verticalMax) {
-        mMaximumEdges[HORIZONTAL] = horizontalMax;
-        mMaximumEdges[VERTICAL] = verticalMax;
-        return this;
-    }
-
-    /**
-     * Sets the delay after entering an activation edge before activation of
-     * auto-scrolling. By default, the activation delay is set to
-     * {@link ViewConfiguration#getTapTimeout()}.
-     * <p>
-     * Specifying a delay of zero will start auto-scrolling immediately after
-     * the touch position enters an activation edge.
-     *
-     * @param delayMillis The activation delay in milliseconds.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setActivationDelay(int delayMillis) {
-        mActivationDelay = delayMillis;
-        return this;
-    }
-
-    /**
-     * Sets the amount of time after activation of auto-scrolling that is takes
-     * to reach target velocity for the current touch position.
-     * <p>
-     * Specifying a duration greater than zero prevents sudden jumps in
-     * velocity.
-     *
-     * @param durationMillis The ramp-up duration in milliseconds.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setRampUpDuration(int durationMillis) {
-        mScroller.setRampUpDuration(durationMillis);
-        return this;
-    }
-
-    /**
-     * Sets the amount of time after de-activation of auto-scrolling that is
-     * takes to slow to a stop.
-     * <p>
-     * Specifying a duration greater than zero prevents sudden jumps in
-     * velocity.
-     *
-     * @param durationMillis The ramp-down duration in milliseconds.
-     * @return The scroll helper, which may used to chain setter calls.
-     */
-    public AutoScrollHelper setRampDownDuration(int durationMillis) {
-        mScroller.setRampDownDuration(durationMillis);
-        return this;
-    }
-
-    /**
-     * Handles touch events by activating automatic scrolling, adjusting scroll
-     * velocity, or stopping.
-     * <p>
-     * If {@link #isExclusive()} is false, always returns false so that
-     * the host view may handle touch events. Otherwise, returns true when
-     * automatic scrolling is active and false otherwise.
-     */
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        if (!mEnabled) {
-            return false;
-        }
-
-        final int action = MotionEventCompat.getActionMasked(event);
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-                mNeedsCancel = true;
-                mAlreadyDelayed = false;
-                // $FALL-THROUGH$
-            case MotionEvent.ACTION_MOVE:
-                final float xTargetVelocity = computeTargetVelocity(
-                        HORIZONTAL, event.getX(), v.getWidth(), mTarget.getWidth());
-                final float yTargetVelocity = computeTargetVelocity(
-                        VERTICAL, event.getY(), v.getHeight(), mTarget.getHeight());
-                mScroller.setTargetVelocity(xTargetVelocity, yTargetVelocity);
-
-                // If the auto scroller was not previously active, but it should
-                // be, then update the state and start animations.
-                if (!mAnimating && shouldAnimate()) {
-                    startAnimating();
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                requestStop();
-                break;
-        }
-
-        return mExclusive && mAnimating;
-    }
-
-    /**
-     * @return whether the target is able to scroll in the requested direction
-     */
-    private boolean shouldAnimate() {
-        final ClampedScroller scroller = mScroller;
-        final int verticalDirection = scroller.getVerticalDirection();
-        final int horizontalDirection = scroller.getHorizontalDirection();
-
-        return verticalDirection != 0 && canTargetScrollVertically(verticalDirection)
-                || horizontalDirection != 0 && canTargetScrollHorizontally(horizontalDirection);
-    }
-
-    /**
-     * Starts the scroll animation.
-     */
-    private void startAnimating() {
-        if (mRunnable == null) {
-            mRunnable = new ScrollAnimationRunnable();
-        }
-
-        mAnimating = true;
-        mNeedsReset = true;
-
-        if (!mAlreadyDelayed && mActivationDelay > 0) {
-            ViewCompat.postOnAnimationDelayed(mTarget, mRunnable, mActivationDelay);
-        } else {
-            mRunnable.run();
-        }
-
-        // If we start animating again before the user lifts their finger, we
-        // already know it's not a tap and don't need an activation delay.
-        mAlreadyDelayed = true;
-    }
-
-    /**
-     * Requests that the scroll animation slow to a stop. If there is an
-     * activation delay, this may occur between posting the animation and
-     * actually running it.
-     */
-    private void requestStop() {
-        if (mNeedsReset) {
-            // The animation has been posted, but hasn't run yet. Manually
-            // stopping animation will prevent it from running.
-            mAnimating = false;
-        } else {
-            mScroller.requestStop();
-        }
-    }
-
-    private float computeTargetVelocity(
-            int direction, float coordinate, float srcSize, float dstSize) {
-        final float relativeEdge = mRelativeEdges[direction];
-        final float maximumEdge = mMaximumEdges[direction];
-        final float value = getEdgeValue(relativeEdge, srcSize, maximumEdge, coordinate);
-        if (value == 0) {
-            // The edge in this direction is not activated.
-            return 0;
-        }
-
-        final float relativeVelocity = mRelativeVelocity[direction];
-        final float minimumVelocity = mMinimumVelocity[direction];
-        final float maximumVelocity = mMaximumVelocity[direction];
-        final float targetVelocity = relativeVelocity * dstSize;
-
-        // Target velocity is adjusted for interpolated edge position, then
-        // clamped to the minimum and maximum values. Later, this value will be
-        // adjusted for time-based acceleration.
-        if (value > 0) {
-            return constrain(value * targetVelocity, minimumVelocity, maximumVelocity);
-        } else {
-            return -constrain(-value * targetVelocity, minimumVelocity, maximumVelocity);
-        }
-    }
-
-    /**
-     * Override this method to scroll the target view by the specified number of
-     * pixels.
-     *
-     * @param deltaX The number of pixels to scroll by horizontally.
-     * @param deltaY The number of pixels to scroll by vertically.
-     */
-    public abstract void scrollTargetBy(int deltaX, int deltaY);
-
-    /**
-     * Override this method to return whether the target view can be scrolled
-     * horizontally in a certain direction.
-     *
-     * @param direction Negative to check scrolling left, positive to check
-     *            scrolling right.
-     * @return true if the target view is able to horizontally scroll in the
-     *         specified direction.
-     */
-    public abstract boolean canTargetScrollHorizontally(int direction);
-
-    /**
-     * Override this method to return whether the target view can be scrolled
-     * vertically in a certain direction.
-     *
-     * @param direction Negative to check scrolling up, positive to check
-     *            scrolling down.
-     * @return true if the target view is able to vertically scroll in the
-     *         specified direction.
-     */
-    public abstract boolean canTargetScrollVertically(int direction);
-
-    /**
-     * Returns the interpolated position of a touch point relative to an edge
-     * defined by its relative inset, its maximum absolute inset, and the edge
-     * interpolator.
-     *
-     * @param relativeValue The size of the inset relative to the total size.
-     * @param size Total size.
-     * @param maxValue The maximum size of the inset, used to clamp (relative *
-     *            total).
-     * @param current Touch position within within the total size.
-     * @return Interpolated value of the touch position within the edge.
-     */
-    private float getEdgeValue(float relativeValue, float size, float maxValue, float current) {
-        // For now, leading and trailing edges are always the same size.
-        final float edgeSize = constrain(relativeValue * size, NO_MIN, maxValue);
-        final float valueLeading = constrainEdgeValue(current, edgeSize);
-        final float valueTrailing = constrainEdgeValue(size - current, edgeSize);
-        final float value = (valueTrailing - valueLeading);
-        final float interpolated;
-        if (value < 0) {
-            interpolated = -mEdgeInterpolator.getInterpolation(-value);
-        } else if (value > 0) {
-            interpolated = mEdgeInterpolator.getInterpolation(value);
-        } else {
-            return 0;
-        }
-
-        return constrain(interpolated, -1, 1);
-    }
-
-    private float constrainEdgeValue(float current, float leading) {
-        if (leading == 0) {
-            return 0;
-        }
-
-        switch (mEdgeType) {
-            case EDGE_TYPE_INSIDE:
-            case EDGE_TYPE_INSIDE_EXTEND:
-                if (current < leading) {
-                    if (current > 0) {
-                        // Movement up to the edge is scaled.
-                        return 1f - current / leading;
-                    } else if (mAnimating && (mEdgeType == EDGE_TYPE_INSIDE_EXTEND)) {
-                        // Movement beyond the edge is always maximum.
-                        return 1f;
-                    }
-                }
-                break;
-            case EDGE_TYPE_OUTSIDE:
-                if (current < 0) {
-                    // Movement beyond the edge is scaled.
-                    return current / -leading;
-                }
-                break;
-        }
-
-        return 0;
-    }
-
-    private static int constrain(int value, int min, int max) {
-        if (value > max) {
-            return max;
-        } else if (value < min) {
-            return min;
-        } else {
-            return value;
-        }
-    }
-
-    private static float constrain(float value, float min, float max) {
-        if (value > max) {
-            return max;
-        } else if (value < min) {
-            return min;
-        } else {
-            return value;
-        }
-    }
-
-    /**
-     * Sends a {@link MotionEvent#ACTION_CANCEL} event to the target view,
-     * canceling any ongoing touch events.
-     */
-    private void cancelTargetTouch() {
-        final long eventTime = SystemClock.uptimeMillis();
-        final MotionEvent cancel = MotionEvent.obtain(
-                eventTime, eventTime, MotionEvent.ACTION_CANCEL, 0, 0, 0);
-        mTarget.onTouchEvent(cancel);
-        cancel.recycle();
-    }
-
-    private class ScrollAnimationRunnable implements Runnable {
-        @Override
-        public void run() {
-            if (!mAnimating) {
-                return;
-            }
-
-            if (mNeedsReset) {
-                mNeedsReset = false;
-                mScroller.start();
-            }
-
-            final ClampedScroller scroller = mScroller;
-            if (scroller.isFinished() || !shouldAnimate()) {
-                mAnimating = false;
-                return;
-            }
-
-            if (mNeedsCancel) {
-                mNeedsCancel = false;
-                cancelTargetTouch();
-            }
-
-            scroller.computeScrollDelta();
-
-            final int deltaX = scroller.getDeltaX();
-            final int deltaY = scroller.getDeltaY();
-            scrollTargetBy(deltaX,  deltaY);
-
-            // Keep going until the scroller has permanently stopped.
-            ViewCompat.postOnAnimation(mTarget, this);
-        }
-    }
-
-    /**
-     * Scroller whose velocity follows the curve of an {@link Interpolator} and
-     * is clamped to the interpolated 0f value before starting and the
-     * interpolated 1f value after a specified duration.
-     */
-    private static class ClampedScroller {
-        private int mRampUpDuration;
-        private int mRampDownDuration;
-        private float mTargetVelocityX;
-        private float mTargetVelocityY;
-
-        private long mStartTime;
-
-        private long mDeltaTime;
-        private int mDeltaX;
-        private int mDeltaY;
-
-        private long mStopTime;
-        private float mStopValue;
-        private int mEffectiveRampDown;
-
-        /**
-         * Creates a new ramp-up scroller that reaches full velocity after a
-         * specified duration.
-         */
-        public ClampedScroller() {
-            mStartTime = Long.MIN_VALUE;
-            mStopTime = -1;
-            mDeltaTime = 0;
-            mDeltaX = 0;
-            mDeltaY = 0;
-        }
-
-        public void setRampUpDuration(int durationMillis) {
-            mRampUpDuration = durationMillis;
-        }
-
-        public void setRampDownDuration(int durationMillis) {
-            mRampDownDuration = durationMillis;
-        }
-
-        /**
-         * Starts the scroller at the current animation time.
-         */
-        public void start() {
-            mStartTime = AnimationUtils.currentAnimationTimeMillis();
-            mStopTime = -1;
-            mDeltaTime = mStartTime;
-            mStopValue = 0.5f;
-            mDeltaX = 0;
-            mDeltaY = 0;
-        }
-
-        /**
-         * Stops the scroller at the current animation time.
-         */
-        public void requestStop() {
-            final long currentTime = AnimationUtils.currentAnimationTimeMillis();
-            mEffectiveRampDown = constrain((int) (currentTime - mStartTime), 0, mRampDownDuration);
-            mStopValue = getValueAt(currentTime);
-            mStopTime = currentTime;
-        }
-
-        public boolean isFinished() {
-            return mStopTime > 0
-                    && AnimationUtils.currentAnimationTimeMillis() > mStopTime + mEffectiveRampDown;
-        }
-
-        private float getValueAt(long currentTime) {
-            if (currentTime < mStartTime) {
-                return 0f;
-            } else if (mStopTime < 0 || currentTime < mStopTime) {
-                final long elapsedSinceStart = currentTime - mStartTime;
-                return 0.5f * constrain(elapsedSinceStart / (float) mRampUpDuration, 0, 1);
-            } else {
-                final long elapsedSinceEnd = currentTime - mStopTime;
-                return (1 - mStopValue) + mStopValue
-                        * constrain(elapsedSinceEnd / (float) mEffectiveRampDown, 0, 1);
-            }
-        }
-
-        /**
-         * Interpolates the value along a parabolic curve corresponding to the equation
-         * <code>y = -4x * (x-1)</code>.
-         *
-         * @param value The value to interpolate, between 0 and 1.
-         * @return the interpolated value, between 0 and 1.
-         */
-        private float interpolateValue(float value) {
-            return -4 * value * value + 4 * value;
-        }
-
-        /**
-         * Computes the current scroll deltas. This usually only be called after
-         * starting the scroller with {@link #start()}.
-         *
-         * @see #getDeltaX()
-         * @see #getDeltaY()
-         */
-        public void computeScrollDelta() {
-            if (mDeltaTime == 0) {
-                throw new RuntimeException("Cannot compute scroll delta before calling start()");
-            }
-
-            final long currentTime = AnimationUtils.currentAnimationTimeMillis();
-            final float value = getValueAt(currentTime);
-            final float scale = interpolateValue(value);
-            final long elapsedSinceDelta = currentTime - mDeltaTime;
-
-            mDeltaTime = currentTime;
-            mDeltaX = (int) (elapsedSinceDelta * scale * mTargetVelocityX);
-            mDeltaY = (int) (elapsedSinceDelta * scale * mTargetVelocityY);
-        }
-
-        /**
-         * Sets the target velocity for this scroller.
-         *
-         * @param x The target X velocity in pixels per millisecond.
-         * @param y The target Y velocity in pixels per millisecond.
-         */
-        public void setTargetVelocity(float x, float y) {
-            mTargetVelocityX = x;
-            mTargetVelocityY = y;
-        }
-
-        public int getHorizontalDirection() {
-            return (int) (mTargetVelocityX / Math.abs(mTargetVelocityX));
-        }
-
-        public int getVerticalDirection() {
-            return (int) (mTargetVelocityY / Math.abs(mTargetVelocityY));
-        }
-
-        /**
-         * The distance traveled in the X-coordinate computed by the last call
-         * to {@link #computeScrollDelta()}.
-         */
-        public int getDeltaX() {
-            return mDeltaX;
-        }
-
-        /**
-         * The distance traveled in the Y-coordinate computed by the last call
-         * to {@link #computeScrollDelta()}.
-         */
-        public int getDeltaY() {
-            return mDeltaY;
-        }
-    }
-}
\ No newline at end of file
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index 9ee3f64..a71d9b2 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -26,6 +26,7 @@
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
 import android.os.SystemClock;
+import android.support.v4.widget.AutoScrollHelper;
 import android.text.InputType;
 import android.text.Selection;
 import android.text.Spannable;
diff --git a/src/com/android/launcher3/FolderAutoScrollHelper.java b/src/com/android/launcher3/FolderAutoScrollHelper.java
index 3c2b449..40e8884 100644
--- a/src/com/android/launcher3/FolderAutoScrollHelper.java
+++ b/src/com/android/launcher3/FolderAutoScrollHelper.java
@@ -16,6 +16,7 @@
 
 package com.android.launcher3;
 
+import android.support.v4.widget.AutoScrollHelper;
 import android.widget.ScrollView;
 
 /**
