diff --git a/src/com/android/launcher3/AutoScrollHelper.java b/src/com/android/launcher3/AutoScrollHelper.java
new file mode 100644
index 0000000..9a7c3b0
--- /dev/null
+++ b/src/com/android/launcher3/AutoScrollHelper.java
@@ -0,0 +1,867 @@
+/*
+ * 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 2500 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 = 2500;
+    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/AutoScroller.java b/src/com/android/launcher3/AutoScroller.java
deleted file mode 100644
index ac8e2e6..0000000
--- a/src/com/android/launcher3/AutoScroller.java
+++ /dev/null
@@ -1,423 +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.graphics.Rect;
-import android.graphics.RectF;
-import android.os.SystemClock;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.animation.AccelerateInterpolator;
-import android.view.animation.Interpolator;
-import android.widget.AbsListView;
-
-class AutoScroller implements View.OnTouchListener, Runnable {
-    private static final int SCALE_RELATIVE = 0;
-    private static final int SCALE_ABSOLUTE = 1;
-
-    private final View mTarget;
-    private final RampUpScroller mScroller;
-
-    /** Interpolator used to scale velocity with touch position, may be null. */
-    private Interpolator mEdgeInterpolator = new AccelerateInterpolator();
-
-    /**
-     * Type of maximum velocity scaling to use, one of:
-     * <ul>
-     * <li>{@link #SCALE_RELATIVE}
-     * <li>{@link #SCALE_ABSOLUTE}
-     * </ul>
-     */
-    private int mMaxVelocityScale = SCALE_RELATIVE;
-
-    /**
-     * Type of activation edge scaling to use, one of:
-     * <ul>
-     * <li>{@link #SCALE_RELATIVE}
-     * <li>{@link #SCALE_ABSOLUTE}
-     * </ul>
-     */
-    private int mActivationEdgeScale = SCALE_RELATIVE;
-
-    /** Edge insets used to activate auto-scrolling. */
-    private RectF mActivationEdges = new RectF(0.2f, 0.2f, 0.2f, 0.2f);
-
-    /** Delay after entering an activation edge before auto-scrolling begins. */
-    private int mActivationDelay;
-
-    /** Maximum horizontal scrolling velocity. */
-    private float mMaxVelocityX = 0.001f;
-
-    /** Maximum vertical scrolling velocity. */
-    private float mMaxVelocityY = 0.001f;
-
-    /**
-     * Whether positive insets should also extend beyond the view bounds when
-     * auto-scrolling is already active. This allows a user to start scrolling
-     * at an inside edge, then move beyond the edge and continue scrolling.
-     */
-    private boolean mExtendsBeyondEdges = true;
-
-    /** Whether to start activation immediately. */
-    private boolean mSkipDelay;
-
-    /** Whether to reset the scroller start time on the next animation. */
-    private boolean mResetScroller;
-
-    /** Whether the auto-scroller is active. */
-    private boolean mActive;
-    private long[] mScrollStart = new long[2];
-
-    /**
-     * If the event is within this percentage of the edge of the scrolling area,
-     * use accelerated scrolling.
-     */
-    private float mFastScrollingRange = 0.8f;
-
-    /**
-     * Duration of time spent in accelerated scrolling area before reaching
-     * maximum velocity
-     */
-    private float mDurationToMax = 2500f;
-
-    private static final int X = 0;
-    private static final int Y = 1;
-
-    public AutoScroller(View target) {
-        mTarget = target;
-        mScroller = new RampUpScroller(250);
-        mActivationDelay = ViewConfiguration.getTapTimeout();
-    }
-
-    /**
-     * Sets the maximum scrolling velocity as a fraction of the host view size
-     * per second. For example, a maximum Y velocity of 1 would scroll one
-     * vertical page per second. By default, both values are 1.
-     *
-     * @param x The maximum X velocity as a fraction of the host view width per
-     *            second.
-     * @param y The maximum Y velocity as a fraction of the host view height per
-     *            second.
-     */
-    public void setMaximumVelocityRelative(float x, float y) {
-        mMaxVelocityScale = SCALE_RELATIVE;
-        mMaxVelocityX = x / 1000f;
-        mMaxVelocityY = y / 1000f;
-    }
-
-    /**
-     * Sets the maximum scrolling velocity as an absolute pixel distance per
-     * second. For example, a maximum Y velocity of 100 would scroll one hundred
-     * pixels per second.
-     *
-     * @param x The maximum X velocity as a fraction of the host view width per
-     *            second.
-     * @param y The maximum Y velocity as a fraction of the host view height per
-     *            second.
-     */
-    public void setMaximumVelocityAbsolute(float x, float y) {
-        mMaxVelocityScale = SCALE_ABSOLUTE;
-        mMaxVelocityX = x / 1000f;
-        mMaxVelocityY = y / 1000f;
-    }
-
-    /**
-     * Sets the delay after entering an activation edge before activation of
-     * auto-scrolling. By default, the activation delay is set to
-     * {@link ViewConfiguration#getTapTimeout()}.
-     *
-     * @param delayMillis The delay in milliseconds.
-     */
-    public void setActivationDelay(int delayMillis) {
-        mActivationDelay = delayMillis;
-    }
-
-    /**
-     * Sets the activation edges in pixels. Edges are treated as insets, so
-     * positive values expand into the view bounds while negative values extend
-     * outside the bounds.
-     *
-     * @param l The left activation edge, in pixels.
-     * @param t The top activation edge, in pixels.
-     * @param r The right activation edge, in pixels.
-     * @param b The bottom activation edge, in pixels.
-     */
-    public void setEdgesAbsolute(int l, int t, int r, int b) {
-        mActivationEdgeScale = SCALE_ABSOLUTE;
-        mActivationEdges.set(l, t, r, b);
-    }
-
-    /**
-     * Whether positive insets should also extend beyond the view bounds when
-     * auto-scrolling is already active. This allows a user to start scrolling
-     * at an inside edge, then move beyond the edge and continue scrolling.
-     *
-     * @param e
-     */
-    public void setExtendsBeyondEdges(boolean e) {
-        mExtendsBeyondEdges = e;
-    }
-
-    /**
-     * Sets the activation edges as fractions of the host view size. Edges are
-     * treated as insets, so positive values expand into the view bounds while
-     * negative values extend outside the bounds. By default, all values are
-     * 0.25.
-     *
-     * @param l The left activation edge, as a fraction of view size.
-     * @param t The top activation edge, as a fraction of view size.
-     * @param r The right activation edge, as a fraction of view size.
-     * @param b The bottom activation edge, as a fraction of view size.
-     */
-    public void setEdgesRelative(float l, float t, float r, float b) {
-        mActivationEdgeScale = SCALE_RELATIVE;
-        mActivationEdges.set(l, t, r, b);
-    }
-
-    /**
-     * Sets the {@link Interpolator} used for scaling touches within activation
-     * edges. By default, uses the {@link AccelerateInterpolator} to gradually
-     * speed up scrolling.
-     *
-     * @param edgeInterpolator The interpolator to use for activation edges, or
-     *            {@code null} to use a fixed velocity during auto-scrolling.
-     */
-    public void setEdgeInterpolator(Interpolator edgeInterpolator) {
-        mEdgeInterpolator = edgeInterpolator;
-    }
-
-    /**
-     * Stop tracking scrolling.
-     */
-    public void stop() {
-        stop(true);
-    }
-
-    /**
-     * Pass the rectangle defining the drawing region for the object used to
-     * trigger drag scrolling.
-     *
-     * @param v View on which the scrolling regions are defined
-     * @param r Rect defining the drawing bounds of the object being dragged
-     * @return whether the event was handled
-     */
-    public boolean onTouch(View v, Rect r) {
-        MotionEvent event = MotionEvent.obtain(SystemClock.uptimeMillis(),
-                SystemClock.uptimeMillis(), MotionEvent.ACTION_MOVE, r.left, r.top, 0);
-        return onTouch(v, event);
-    }
-
-    @Override
-    public boolean onTouch(View v, MotionEvent event) {
-        final int action = event.getActionMasked();
-        switch (action) {
-            case MotionEvent.ACTION_DOWN:
-            case MotionEvent.ACTION_MOVE:
-                final int sourceWidth = v.getWidth();
-                final int sourceHeight = v.getHeight();
-                final float x = event.getX();
-                final float y = event.getY();
-                final float l;
-                final float t;
-                final float r;
-                final float b;
-                final RectF activationEdges = mActivationEdges;
-                if (mActivationEdgeScale == SCALE_ABSOLUTE) {
-                    l = activationEdges.left;
-                    t = activationEdges.top;
-                    r = activationEdges.right;
-                    b = activationEdges.bottom;
-                } else {
-                    l = activationEdges.left * sourceWidth;
-                    t = activationEdges.top * sourceHeight;
-                    r = activationEdges.right * sourceWidth;
-                    b = activationEdges.bottom * sourceHeight;
-                }
-
-                final float maxVelX;
-                final float maxVelY;
-                if (mMaxVelocityScale == SCALE_ABSOLUTE) {
-                    maxVelX = mMaxVelocityX;
-                    maxVelY = mMaxVelocityY;
-                } else {
-                    maxVelX = mMaxVelocityX * mTarget.getWidth();
-                    maxVelY = mMaxVelocityY * mTarget.getHeight();
-                }
-
-                final float velocityX = getEdgeVelocity(X, l, r, x, sourceWidth, event);
-                final float velocityY = getEdgeVelocity(Y, t, b, y, sourceHeight, event);
-                mScroller.setTargetVelocity(velocityX * maxVelX, velocityY * maxVelY);
-
-                if ((velocityX != 0 || velocityY != 0) && !mActive) {
-                    mActive = true;
-                    mResetScroller = true;
-                    if (mSkipDelay) {
-                        mTarget.postOnAnimation(this);
-                    } else {
-                        mSkipDelay = true;
-                        mTarget.postOnAnimationDelayed(this, mActivationDelay);
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-            case MotionEvent.ACTION_CANCEL:
-                stop(true);
-                break;
-        }
-
-        return false;
-    }
-
-    /**
-     * @param leading Size of the leading activation inset.
-     * @param trailing Size of the trailing activation inset.
-     * @param current Position within within the total area.
-     * @param size Size of the total area.
-     * @return The fraction of the activation area.
-     */
-    private float getEdgeVelocity(int dir, float leading, float trailing,
-            float current, float size, MotionEvent ev) {
-        float valueLeading = 0;
-        if (leading > 0) {
-            if (current < leading) {
-                if (current > 0) {
-                    // Movement up to the edge is scaled.
-                    valueLeading = 1f - current / leading;
-                } else if (mActive && mExtendsBeyondEdges) {
-                    // Movement beyond the edge is always maximum.
-                    valueLeading = 1f;
-                }
-            }
-        } else if (leading < 0) {
-            if (current < 0) {
-                // Movement beyond the edge is scaled.
-                valueLeading = current / leading;
-            }
-        }
-
-        float valueTrailing = 0;
-        if (trailing > 0) {
-            if (current > size - trailing) {
-                if (current < size) {
-                    // Movement up to the edge is scaled.
-                    valueTrailing = 1f - (size - current) / trailing;
-                } else if (mActive && mExtendsBeyondEdges) {
-                    // Movement beyond the edge is always maximum.
-                    valueTrailing = 1f;
-                }
-            }
-        } else if (trailing < 0) {
-            if (current > size) {
-                // Movement beyond the edge is scaled.
-                valueTrailing = (size - current) / trailing;
-            }
-        }
-
-        float value = (valueTrailing - valueLeading);
-        if ((value > mFastScrollingRange || value < -mFastScrollingRange)
-            && mScrollStart[dir] == 0) {
-            // within auto scrolling area
-            mScrollStart[dir] = ev.getEventTime();
-        } else {
-            // Outside fast scrolling area; reset duration
-            mScrollStart[dir] = 0;
-        }
-        final float duration = (ev.getEventTime() - mScrollStart[dir])/mDurationToMax;
-        final float interpolated;
-        if (value < 0) {
-            if (value < -mFastScrollingRange) {
-                // Close to top; use duration!
-                value += mEdgeInterpolator.getInterpolation(-duration);
-            }
-            interpolated = mEdgeInterpolator == null ? -1
-                    : -mEdgeInterpolator.getInterpolation(-value);
-        } else if (value > 0) {
-            // Close to bottom; use duration
-            if (value > mFastScrollingRange) {
-                // Close to bottom; use duration!
-                value += mEdgeInterpolator.getInterpolation(duration);
-            }
-            interpolated = mEdgeInterpolator == null ? 1
-                    : mEdgeInterpolator.getInterpolation(value);
-        } else {
-            mScrollStart[dir] = 0;
-            return 0;
-        }
-
-        return constrain(interpolated, -1, 1);
-    }
-
-    private static float constrain(float value, float min, float max) {
-        if (value > max) {
-            return max;
-        } else if (value < min) {
-            return min;
-        } else {
-            return value;
-        }
-    }
-
-    /**
-     * Stops auto-scrolling immediately, optionally reseting the auto-scrolling
-     * delay.
-     *
-     * @param reset Whether to reset the auto-scrolling delay.
-     */
-    private void stop(boolean reset) {
-        mActive = false;
-        mSkipDelay = !reset;
-        mTarget.removeCallbacks(this);
-    }
-
-    @Override
-    public void run() {
-        if (!mActive) {
-            return;
-        }
-
-        if (mResetScroller) {
-            mResetScroller = false;
-            mScroller.start();
-        }
-
-        final View target = mTarget;
-        final RampUpScroller scroller = mScroller;
-        final float targetVelocityX = scroller.getTargetVelocityX();
-        final float targetVelocityY = scroller.getTargetVelocityY();
-        if ((targetVelocityY == 0 || !target.canScrollVertically(targetVelocityY > 0 ? 1 : -1)
-                && (targetVelocityX == 0
-                        || !target.canScrollHorizontally(targetVelocityX > 0 ? 1 : -1)))) {
-            stop(false);
-            return;
-        }
-
-        scroller.computeScrollDelta();
-
-        final int deltaX = scroller.getDeltaX();
-        final int deltaY = scroller.getDeltaY();
-
-        if (target instanceof AbsListView) {
-            final AbsListView list = (AbsListView) target;
-            list.smoothScrollBy(deltaY, 0);
-        } else {
-            target.scrollBy(deltaX, deltaY);
-        }
-
-        target.postOnAnimation(this);
-    }
-}
diff --git a/src/com/android/launcher3/Folder.java b/src/com/android/launcher3/Folder.java
index f57ff07..33d300c 100644
--- a/src/com/android/launcher3/Folder.java
+++ b/src/com/android/launcher3/Folder.java
@@ -25,6 +25,7 @@
 import android.graphics.PointF;
 import android.graphics.Rect;
 import android.graphics.drawable.Drawable;
+import android.os.SystemClock;
 import android.text.InputType;
 import android.text.Selection;
 import android.text.Spannable;
@@ -107,8 +108,6 @@
     private float mFolderIconPivotX;
     private float mFolderIconPivotY;
 
-    private static final float MAX_SCROLL_VELOCITY = 1500f;
-
     private boolean mIsEditingName = false;
     private InputMethodManager mInputMethodManager;
 
@@ -121,7 +120,7 @@
 
     private boolean mDestroyed;
 
-    private AutoScroller mAutoScroller;
+    private AutoScrollHelper mAutoScrollHelper;
 
     private Runnable mDeferredAction;
     private boolean mDeferDropAfterUninstall;
@@ -193,9 +192,7 @@
         mFolderName.setSelectAllOnFocus(true);
         mFolderName.setInputType(mFolderName.getInputType() |
                 InputType.TYPE_TEXT_FLAG_NO_SUGGESTIONS | InputType.TYPE_TEXT_FLAG_CAP_WORDS);
-        mAutoScroller = new AutoScroller(mScrollView);
-        mAutoScroller.setMaximumVelocityAbsolute(MAX_SCROLL_VELOCITY, MAX_SCROLL_VELOCITY);
-        mAutoScroller.setExtendsBeyondEdges(false);
+        mAutoScrollHelper = new FolderAutoScrollHelper(mScrollView);
     }
 
     private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {
@@ -626,24 +623,29 @@
         return (getLayoutDirection() == LAYOUT_DIRECTION_RTL);
     }
 
-    private Rect getDragObjectDrawingRect(View dragView, float[] r) {
-        final Rect drawingRect = mTempRect;
-        drawingRect.left = (int) r[0];
-        drawingRect.top = (int) r[1];
-        drawingRect.right = drawingRect.left + dragView.getMeasuredWidth();
-        drawingRect.bottom = drawingRect.top + dragView.getMeasuredHeight();
-        return drawingRect;
-    }
-
     public void onDragOver(DragObject d) {
-        int scrollOffset = mScrollView.getScrollY();
-        float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, d.dragView, null);
+        final DragView dragView = d.dragView;
+        final int scrollOffset = mScrollView.getScrollY();
+        final float[] r = getDragViewVisualCenter(d.x, d.y, d.xOffset, d.yOffset, dragView, null);
         r[0] -= getPaddingLeft();
         r[1] -= getPaddingTop();
-        if (!mAutoScroller.onTouch(this, getDragObjectDrawingRect(d.dragView, r))) {
-            mTargetCell = mContent.findNearestArea((int) r[0], (int) r[1] + scrollOffset, 1, 1,
-                    mTargetCell);
 
+        final long downTime = SystemClock.uptimeMillis();
+        final MotionEvent translatedEv = MotionEvent.obtain(
+                downTime, downTime, MotionEvent.ACTION_MOVE, d.x, d.y, 0);
+
+        if (!mAutoScrollHelper.isEnabled()) {
+            mAutoScrollHelper.setEnabled(true);
+        }
+
+        final boolean handled = mAutoScrollHelper.onTouch(this, translatedEv);
+        translatedEv.recycle();
+
+        if (handled) {
+            mReorderAlarm.cancelAlarm();
+        } else {
+            mTargetCell = mContent.findNearestArea(
+                    (int) r[0], (int) r[1] + scrollOffset, 1, 1, mTargetCell);
             if (isLayoutRtl()) {
                 mTargetCell[0] = mContent.getCountX() - mTargetCell[0] - 1;
             }
@@ -658,8 +660,6 @@
             } else {
                 mDragMode = DRAG_MODE_NONE;
             }
-        } else {
-            mReorderAlarm.cancelAlarm();
         }
     }
 
@@ -705,7 +705,7 @@
 
     public void onDragExit(DragObject d) {
         // Exiting folder; stop the auto scroller.
-        mAutoScroller.stop();
+        mAutoScrollHelper.setEnabled(false);
         // We only close the folder if this is a true drag exit, ie. not because
         // a drop has occurred above the folder.
         if (!d.dragComplete) {
diff --git a/src/com/android/launcher3/FolderAutoScrollHelper.java b/src/com/android/launcher3/FolderAutoScrollHelper.java
new file mode 100644
index 0000000..d7e6770
--- /dev/null
+++ b/src/com/android/launcher3/FolderAutoScrollHelper.java
@@ -0,0 +1,56 @@
+/*
+ * 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.widget.ScrollView;
+
+/**
+ * An implementation of {@link AutoScrollHelper} that knows how to scroll
+ * through a {@link Folder}.
+ */
+public class FolderAutoScrollHelper extends AutoScrollHelper {
+    private static final float MAX_SCROLL_VELOCITY = 1500f;
+
+    private final ScrollView mTarget;
+
+    public FolderAutoScrollHelper(ScrollView target) {
+        super(target);
+
+        mTarget = target;
+
+        setActivationDelay(0);
+        setEdgeType(EDGE_TYPE_INSIDE);
+        setExclusive(true);
+        setMaximumVelocity(MAX_SCROLL_VELOCITY, MAX_SCROLL_VELOCITY);
+    }
+
+    @Override
+    public void scrollTargetBy(int deltaX, int deltaY) {
+        mTarget.scrollBy(deltaX, deltaY);
+    }
+
+    @Override
+    public boolean canTargetScrollHorizontally(int direction) {
+        // List do not scroll horizontally.
+        return false;
+    }
+
+    @Override
+    public boolean canTargetScrollVertically(int direction) {
+        return mTarget.canScrollVertically(direction);
+    }
+}
\ No newline at end of file
