diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index 768f9ba..1626183 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -37,9 +37,9 @@
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
-import com.android.browser.NavTabGallery.OnRemoveListener;
+import com.android.browser.NavTabScroller.OnLayoutListener;
+import com.android.browser.NavTabScroller.OnRemoveListener;
 import com.android.browser.TabControl.OnThumbnailUpdatedListener;
-import com.android.browser.view.Gallery.OnScrollFinishedListener;
 
 import java.util.HashMap;
 
@@ -47,9 +47,6 @@
         implements OnClickListener, OnMenuItemClickListener, OnThumbnailUpdatedListener {
 
 
-    private static final int SCROLL_MIN = 200;
-    private static final int SCROLL_FACTOR = 20;
-
     UiController mUiController;
     PhoneUi mUi;
     Tab mTab;
@@ -66,7 +63,7 @@
     ImageView mFavicon;
     ImageButton mCloseTab;
 
-    NavTabGallery mScroller;
+    NavTabScroller mScroller;
     TabAdapter mAdapter;
     int mOrientation;
     boolean mNeedsMenu;
@@ -81,22 +78,18 @@
         init();
     }
 
-    protected Tab getSelectedTab() {
-        return (Tab) mScroller.getSelectedItem();
-    }
-
     protected void showMenu() {
         PopupMenu popup = new PopupMenu(mContext, mMore);
         Menu menu = popup.getMenu();
         popup.getMenuInflater().inflate(R.menu.browser, menu);
-        mUiController.updateMenuState(mScroller.getSelectedItem(), menu);
+        mUiController.updateMenuState(mUiController.getCurrentTab(), menu);
         popup.setOnMenuItemClickListener(this);
         popup.show();
     }
 
     @Override
     public boolean onMenuItemClick(MenuItem item) {
-        mUi.hideNavScreen(false);
+        mUi.hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
         return mUiController.onOptionsItemSelected(item);
     }
 
@@ -104,15 +97,14 @@
         return mActivity.getResources().getDimension(R.dimen.toolbar_height);
     }
 
-    // for configuration changes
     @Override
     protected void onConfigurationChanged(Configuration newconfig) {
         if (newconfig.orientation != mOrientation) {
-            int selIx = mScroller.getSelectionIndex();
+            int sv = mScroller.getScrollValue();
             removeAllViews();
             mOrientation = newconfig.orientation;
             init();
-            mScroller.setSelection(selIx);
+            mScroller.setScrollValue(sv);
             mAdapter.notifyDataSetChanged();
         }
     }
@@ -127,7 +119,7 @@
         mBookmarks.setOnClickListener(this);
         mNewTab.setOnClickListener(this);
         mMore.setOnClickListener(this);
-        mScroller = (NavTabGallery) findViewById(R.id.scroller);
+        mScroller = (NavTabScroller) findViewById(R.id.scroller);
         TabControl tc = mUiController.getTabControl();
         mTabViews = new HashMap<Tab, View>(tc.getTabCount());
         mAdapter = new TabAdapter(mContext, tc);
@@ -150,28 +142,12 @@
 
     @Override
     public void onClick(View v) {
-        WebView web = (mTab != null) ? mTab.getWebView() : null;
-        if (web != null) {
-            if (mForward == v) {
-                mUi.hideNavScreen(true);
-                mTab.goForward();
-            } else if (mRefresh == v) {
-                mUi.hideNavScreen(true);
-                web.reload();
-            }
-        }
         if (mBookmarks == v) {
-            switchToSelected();
             mUiController.bookmarksOrHistoryPicker(false);
         } else if (mNewTab == v) {
             openNewTab();
         } else if (mMore == v) {
             showMenu();
-        } else if (mTitle == v) {
-            mUi.getTitleBar().setSkipTitleBarAnimations(true);
-            close(false);
-            mUi.editUrl(false);
-            mUi.getTitleBar().setSkipTitleBarAnimations(false);
         }
     }
 
@@ -182,49 +158,46 @@
             } else {
                 mUiController.closeTab(tab);
             }
-            mAdapter.notifyDataSetChanged();
+            mScroller.handleDataChanged();
         }
     }
 
     private void openNewTab() {
         // need to call openTab explicitely with setactive false
-        Tab tab = mUiController.openTab(BrowserSettings.getInstance().getHomePage(),
+        final Tab tab = mUiController.openTab(BrowserSettings.getInstance().getHomePage(),
                 false, false, false);
-        int duration = 0;
         if (tab != null) {
             mUiController.setBlockEvents(true);
-            int oldsel = mScroller.getSelectedItemPosition();
             final int tix = mUi.mTabControl.getTabPosition(tab);
-            duration = SCROLL_MIN + SCROLL_FACTOR * Math.abs(oldsel - tix);
-            mScroller.handleDataChanged();
-            mScroller.smoothScrollToPosition(tix, duration, new OnScrollFinishedListener() {
+            mScroller.setOnLayoutListener(new OnLayoutListener() {
+
                 @Override
-                public void onScrollFinished() {
-                    mUiController.setBlockEvents(false);
-                    mUi.hideNavScreen(true);
-                    switchToSelected();
+                public void onLayout(int l, int t, int r, int b) {
+                    mUi.hideNavScreen(tix, true);
+                    switchToTab(tab);
                 }
             });
+            mScroller.handleDataChanged(tix);
+            mUiController.setBlockEvents(false);
         }
     }
 
-    View getSelectedTabView() {
-        return mScroller.getSelectedTab();
-    }
-
-    private void switchToSelected() {
-        Tab tab = (Tab) mScroller.getSelectedItem();
+    private void switchToTab(Tab tab) {
         if (tab != mUi.getActiveTab()) {
             mUiController.setActiveTab(tab);
         }
     }
 
-    protected void close() {
-        close(true);
+    protected void close(int position) {
+        close(position, true);
     }
 
-    protected void close(boolean animate) {
-        mUi.hideNavScreen(animate);
+    protected void close(int position, boolean animate) {
+        mUi.hideNavScreen(position, animate);
+    }
+
+    protected NavTabView getTabView(int pos) {
+        return mScroller.getTabView(pos);
     }
 
     class TabAdapter extends BaseAdapter {
@@ -263,15 +236,13 @@
                     if (tabview.isClose(v)) {
                         mScroller.animateOut(tabview);
                     } else if (tabview.isTitle(v)) {
-                        mScroller.setSelection(position);
-                        switchToSelected();
+                        switchToTab(tab);
                         mUi.getTitleBar().setSkipTitleBarAnimations(true);
-                        close(false);
+                        close(position, false);
                         mUi.editUrl(false);
                         mUi.getTitleBar().setSkipTitleBarAnimations(false);
                     } else if (tabview.isWebView(v)) {
-                        mScroller.setSelection(position);
-                        close();
+                        close(position);
                     }
                 }
             });
@@ -285,7 +256,6 @@
         View v = mTabViews.get(t);
         if (v != null) {
             v.invalidate();
-            mScroller.invalidate();
         }
     }
 
diff --git a/src/com/android/browser/NavTabGallery.java b/src/com/android/browser/NavTabGallery.java
deleted file mode 100644
index af02e8d..0000000
--- a/src/com/android/browser/NavTabGallery.java
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- * Copyright (C) 2011 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.browser;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-
-import com.android.browser.view.Gallery;
-
-/**
- * custom view for displaying tabs in the nav screen
- */
-public class NavTabGallery extends Gallery {
-
-    interface OnRemoveListener {
-        public void onRemovePosition(int position);
-    }
-
-    // after drag animation velocity in pixels/sec
-    private static final float MIN_VELOCITY = 1500;
-
-    private OnRemoveListener mRemoveListener;
-    private boolean mBlockUpCallback;
-    private Animator mAnimator;
-
-    public NavTabGallery(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-    }
-
-    public NavTabGallery(Context context, AttributeSet attrs) {
-        super(context, attrs);
-    }
-
-    public NavTabGallery(Context context) {
-        super(context);
-    }
-
-    public void setOnRemoveListener(OnRemoveListener l) {
-        mRemoveListener = l;
-    }
-
-    protected void setSelection(int ix) {
-        super.setSelectedPositionInt(ix);
-    }
-
-    protected int getSelectionIndex() {
-        return getSelectedItemPosition();
-    }
-
-    protected Tab getSelectedItem() {
-        return (Tab) mAdapter.getItem(getSelectedItemPosition());
-    }
-
-    View getSelectedTab() {
-        return getSelectedView();
-    }
-
-    @Override
-    protected void onOrthoDrag(View v, MotionEvent down, MotionEvent move,
-            float distance) {
-        if (mAnimator == null) {
-            offsetView(v, - distance);
-        }
-    }
-
-    @Override
-    protected void onOrthoFling(View v, MotionEvent down, MotionEvent move,
-            float velocity) {
-        if ((mAnimator == null) && (Math.abs(velocity) > MIN_VELOCITY)) {
-            mBlockUpCallback = true;
-            animateOut(v, velocity);
-        }
-    }
-
-    @Override
-    protected void onUp(View downView) {
-        if (mAnimator != null) return;
-        if (mBlockUpCallback) {
-            mBlockUpCallback = false;
-            return;
-        }
-        if (mIsOrthoDragged && downView != null) {
-            // offset
-            int diff = calculateTop(downView, false) - (mHorizontal ? downView.getTop()
-                    : downView.getLeft());
-            if (Math.abs(diff) > (mHorizontal ? downView.getHeight() : downView.getWidth()) / 2) {
-                // remove it
-                animateOut(downView, - Math.signum(diff) * MIN_VELOCITY);
-            } else {
-                // snap back
-                offsetView(downView, diff);
-            }
-        } else {
-            super.onUp(downView);
-        }
-    }
-
-    private void offsetView(View v, float distance) {
-        if (mHorizontal) {
-            v.offsetTopAndBottom((int) distance);
-        } else {
-            v.offsetLeftAndRight((int) distance);
-        }
-    }
-
-    protected void animateOut(View v) {
-        animateOut(v, -MIN_VELOCITY);
-    }
-
-    private void animateOut(final View v, float velocity) {
-        if ((v == null) || (mAnimator != null)) return;
-        final int position = mFirstPosition + indexOfChild(v);
-        int target = 0;
-        if (velocity < 0) {
-            target = mHorizontal ? -v.getHeight() :  - v.getWidth();
-        } else {
-            target = mHorizontal ? getHeight() : getWidth();
-        }
-        int distance = target - (mHorizontal ? v.getTop() : v.getLeft());
-        long duration = (long) (Math.abs(distance) * 1000 / Math.abs(velocity));
-        if (mHorizontal) {
-            mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_Y, 0, target);
-        } else {
-            mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_X, 0, target);
-        }
-        mAnimator.setDuration(duration);
-        mAnimator.addListener(new AnimatorListenerAdapter() {
-            public void onAnimationEnd(Animator a) {
-                if (mRemoveListener !=  null) {
-                    boolean needsGap = position < (mAdapter.getCount() - 1);
-                    if (needsGap) {
-                        setGapPosition(position, mHorizontal ? v.getWidth() : v.getHeight());
-                    }
-                    mRemoveListener.onRemovePosition(position);
-                    if (!needsGap && (position > 0) && (mAdapter.getCount() > 0)) {
-                        scrollToChild(position - 1);
-                    }
-                    mAnimator = null;
-                }
-            }
-        });
-        mAnimator.start();
-    }
-
-}
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
new file mode 100644
index 0000000..03bf595
--- /dev/null
+++ b/src/com/android/browser/NavTabScroller.java
@@ -0,0 +1,516 @@
+/*
+ * Copyright (C) 2011 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.browser;
+
+
+import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
+import android.animation.AnimatorSet;
+import android.animation.ObjectAnimator;
+import android.content.Context;
+import android.database.DataSetObserver;
+import android.graphics.Canvas;
+import android.util.AttributeSet;
+import android.view.Gravity;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.animation.DecelerateInterpolator;
+import android.widget.BaseAdapter;
+import android.widget.LinearLayout;
+
+import com.android.browser.view.ScrollerView;
+
+/**
+ * custom view for displaying tabs in the nav screen
+ */
+public class NavTabScroller extends ScrollerView {
+
+    static final int INVALID_POSITION = -1;
+    static final float[] PULL_FACTOR = { 2.5f, 0.9f };
+
+    interface OnRemoveListener {
+        public void onRemovePosition(int position);
+    }
+
+    interface OnLayoutListener {
+        public void onLayout(int l, int t, int r, int b);
+    }
+
+    private ContentLayout mContentView;
+    private BaseAdapter mAdapter;
+    private OnRemoveListener mRemoveListener;
+    private OnLayoutListener mLayoutListener;
+    private int mGap;
+    private int mGapPosition;
+    private ObjectAnimator mGapAnimator;
+
+    // after drag animation velocity in pixels/sec
+    private static final float MIN_VELOCITY = 1500;
+    private Animator mAnimator;
+
+    private float mFlingVelocity;
+    private boolean mNeedsScroll;
+    private int mScrollPosition;
+
+    DecelerateInterpolator mCubic;
+    int mPullValue;
+
+    public NavTabScroller(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init(context);
+    }
+
+    public NavTabScroller(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init(context);
+    }
+
+    public NavTabScroller(Context context) {
+        super(context);
+        init(context);
+    }
+
+    private void init(Context ctx) {
+        mCubic = new DecelerateInterpolator(1.5f);
+        mGapPosition = INVALID_POSITION;
+        setHorizontalScrollBarEnabled(false);
+        setVerticalScrollBarEnabled(false);
+        mContentView = new ContentLayout(ctx, this);
+        mContentView.setOrientation(LinearLayout.HORIZONTAL);
+        addView(mContentView);
+        mContentView.setLayoutParams(
+                new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
+        // ProGuard !
+        setGap(getGap());
+        mFlingVelocity = getContext().getResources().getDisplayMetrics().density
+                * MIN_VELOCITY;
+    }
+
+    protected int getScrollValue() {
+        return mHorizontal ? mScrollX : mScrollY;
+    }
+
+    protected void setScrollValue(int value) {
+        scrollTo(mHorizontal ? value : 0, mHorizontal ? 0 : value);
+    }
+
+    protected NavTabView getTabView(int pos) {
+        return (NavTabView) mContentView.getChildAt(pos);
+    }
+
+    /**
+     * define a visual gap in the list of items
+     * the gap is rendered in front (left or above)
+     * the given position
+     * @param position
+     * @param gap
+     */
+    public void setGapPosition(int position, int gap) {
+        mGapPosition = position;
+        mGap = gap;
+    }
+
+    public void setGap(int gap) {
+        if (mGapPosition != INVALID_POSITION) {
+            mGap = gap;
+            postInvalidate();
+        }
+    }
+
+    public int getGap() {
+        return mGap;
+    }
+
+    protected boolean isHorizontal() {
+        return mHorizontal;
+    }
+
+    public void setOrientation(int orientation) {
+        mContentView.setOrientation(orientation);
+        if (orientation == LinearLayout.HORIZONTAL) {
+            mContentView.setLayoutParams(
+                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
+        } else {
+            mContentView.setLayoutParams(
+                    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
+        }
+        super.setOrientation(orientation);
+    }
+
+    @Override
+    protected void onMeasure(int wspec, int hspec) {
+        super.onMeasure(wspec, hspec);
+        calcPadding();
+    }
+
+    private void calcPadding() {
+        if (mAdapter.getCount() > 0) {
+            View v = mContentView.getChildAt(0);
+            if (mHorizontal) {
+                int pad = (getMeasuredWidth() - v.getMeasuredWidth()) / 2 + 2;
+                mContentView.setPadding(pad, 0, pad, 0);
+            } else {
+                int pad = (getMeasuredHeight() - v.getMeasuredHeight()) / 2 + 2;
+                mContentView.setPadding(0, pad, 0, pad);
+            }
+        }
+    }
+
+    public void setAdapter(BaseAdapter adapter) {
+        setAdapter(adapter, 0);
+    }
+
+
+    public void setOnRemoveListener(OnRemoveListener l) {
+        mRemoveListener = l;
+    }
+
+    public void setOnLayoutListener(OnLayoutListener l) {
+        mLayoutListener = l;
+    }
+
+    protected void setAdapter(BaseAdapter adapter, int selection) {
+        mAdapter = adapter;
+        mAdapter.registerDataSetObserver(new DataSetObserver() {
+
+            @Override
+            public void onChanged() {
+                super.onChanged();
+                handleDataChanged();
+            }
+
+            @Override
+            public void onInvalidated() {
+                super.onInvalidated();
+            }
+        });
+        handleDataChanged(selection);
+    }
+
+    protected ViewGroup getContentView() {
+        return mContentView;
+    }
+
+    protected int getRelativeChildTop(int ix) {
+        return mContentView.getChildAt(ix).getTop() - mScrollY;
+    }
+
+    protected void handleDataChanged() {
+        handleDataChanged(INVALID_POSITION);
+    }
+
+    protected void handleDataChanged(int newscroll) {
+        int scroll = getScrollValue();
+        if (mGapAnimator != null) {
+            mGapAnimator.cancel();
+        }
+        mContentView.removeAllViews();
+        for (int i = 0; i < mAdapter.getCount(); i++) {
+            View v = mAdapter.getView(i, null, mContentView);
+            LinearLayout.LayoutParams lp = new LinearLayout.LayoutParams(
+                    LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
+            lp.gravity = (mHorizontal ? Gravity.CENTER_VERTICAL : Gravity.CENTER_HORIZONTAL);
+            mContentView.addView(v, lp);
+            if ((mGapPosition > INVALID_POSITION) && (i >= mGapPosition)) {
+                adjustViewGap(v, mGap);
+            }
+        }
+        if (newscroll > INVALID_POSITION) {
+            newscroll = Math.min(mAdapter.getCount() - 1, newscroll);
+            mNeedsScroll = true;
+            mScrollPosition = newscroll;
+            requestLayout();
+        } else {
+            setScrollValue(scroll);
+        }
+        if (mGapPosition > INVALID_POSITION) {
+            mGapAnimator = ObjectAnimator.ofInt(this, "gap", mGap, 0);
+            mGapAnimator.setDuration(250);
+            mGapAnimator.addListener(new AnimatorListenerAdapter() {
+                @Override
+                public void onAnimationEnd(Animator a) {
+                    mGap = 0;
+                    adjustGap();
+                    mGapPosition = INVALID_POSITION;
+                    mGapAnimator = null;
+                    mContentView.requestLayout();
+                }
+            });
+            mGapAnimator.start();
+        }
+
+    }
+
+    protected void finishScroller() {
+        mScroller.forceFinished(true);
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        if (mNeedsScroll) {
+            mScroller.forceFinished(true);
+            snapToSelected(mScrollPosition, false);
+            mNeedsScroll = false;
+        }
+        if (mLayoutListener != null) {
+            mLayoutListener.onLayout(l, t, r, b);
+            mLayoutListener = null;
+        }
+    }
+
+    void adjustGap() {
+        for (int i = 0; i < mContentView.getChildCount(); i++) {
+            if (i >= mGapPosition) {
+                final View child = mContentView.getChildAt(i);
+                adjustViewGap(child, mGap);
+            }
+        }
+    }
+
+    private void adjustViewGap(View view, int gap) {
+        if (mHorizontal) {
+            view.setTranslationX(gap);
+        } else {
+            view.setTranslationY(gap);
+        }
+    }
+
+
+    void clearTabs() {
+        mContentView.removeAllViews();
+    }
+
+    void snapToSelected(int pos, boolean smooth) {
+        if (pos < 0) return;
+        View v = mContentView.getChildAt(pos);
+        int sx = 0;
+        int sy = 0;
+        if (mHorizontal) {
+            sx = (v.getLeft() + v.getRight() - getWidth()) / 2;
+        } else {
+            sy = (v.getTop() + v.getBottom() - getHeight()) / 2;
+        }
+        if ((sx != mScrollX) || (sy != mScrollY)) {
+            if (smooth) {
+                smoothScrollTo(sx,sy);
+            } else {
+                scrollTo(sx, sy);
+            }
+        }
+    }
+
+    protected void animateOut(View v) {
+        if (v == null) return;
+        animateOut(v, -mFlingVelocity);
+    }
+
+    private void animateOut(final View v, float velocity) {
+        float start = mHorizontal ? v.getTranslationY() : v.getTranslationX();
+        animateOut(v, velocity, start);
+    }
+
+    private void animateOut(final View v, float velocity, float start) {
+        if ((v == null) || (mAnimator != null)) return;
+        final int position = mContentView.indexOfChild(v);
+        int target = 0;
+        if (velocity < 0) {
+            target = mHorizontal ? -getHeight() :  -getWidth();
+        } else {
+            target = mHorizontal ? getHeight() : getWidth();
+        }
+        int distance = target - (mHorizontal ? v.getTop() : v.getLeft());
+        long duration = (long) (Math.abs(distance) * 1000 / Math.abs(velocity));
+        if (mHorizontal) {
+            mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_Y, start, target);
+        } else {
+            mAnimator = ObjectAnimator.ofFloat(v, TRANSLATION_X, start, target);
+        }
+        mAnimator.setDuration(duration);
+        mAnimator.addListener(new AnimatorListenerAdapter() {
+            public void onAnimationEnd(Animator a) {
+                if (mRemoveListener !=  null) {
+                    boolean needsGap = position < (mAdapter.getCount() - 1);
+                    if (needsGap) {
+                        setGapPosition(position, mHorizontal ? v.getWidth() : v.getHeight());
+                    }
+                    mRemoveListener.onRemovePosition(position);
+                    mAnimator = null;
+                }
+            }
+        });
+        mAnimator.start();
+    }
+
+    @Override
+    public void draw(Canvas canvas) {
+        super.draw(canvas);
+        if (mGapPosition > INVALID_POSITION) {
+            adjustGap();
+        }
+    }
+
+    @Override
+    protected View findViewAt(int x, int y) {
+        x += mScrollX;
+        y += mScrollY;
+        final int count = mContentView.getChildCount();
+        for (int i = count - 1; i >= 0; i--) {
+            View child = mContentView.getChildAt(i);
+            if (child.getVisibility() == View.VISIBLE) {
+                if ((x >= child.getLeft()) && (x < child.getRight())
+                        && (y >= child.getTop()) && (y < child.getBottom())) {
+                    return child;
+                }
+            }
+        }
+        return null;
+    }
+
+    @Override
+    protected void onOrthoDrag(View v, float distance) {
+        if ((v != null) && (mAnimator == null)) {
+            offsetView(v, distance);
+        }
+    }
+
+    @Override
+    protected void onOrthoDragFinished(View downView) {
+        if (mAnimator != null) return;
+        if (mIsOrthoDragged && downView != null) {
+            // offset
+            float diff = mHorizontal ? downView.getTranslationY() : downView.getTranslationX();
+            if (Math.abs(diff) > (mHorizontal ? downView.getHeight() : downView.getWidth()) / 2) {
+                // remove it
+                animateOut(downView, Math.signum(diff) * mFlingVelocity, diff);
+            } else {
+                // snap back
+                offsetView(downView, 0);
+            }
+        }
+    }
+
+    @Override
+    protected void onOrthoFling(View v, float velocity) {
+        if (v == null) return;
+        if (mAnimator == null && Math.abs(velocity) > mFlingVelocity / 2) {
+            animateOut(v, velocity);
+        } else {
+            offsetView(v, 0);
+        }
+    }
+
+    private void offsetView(View v, float distance) {
+        if (mHorizontal) {
+            v.setTranslationY(distance);
+        } else {
+            v.setTranslationX(distance);
+        }
+    }
+
+    private float ease(DecelerateInterpolator inter, float value, float start, float dist, float duration) {
+        return start + dist * inter.getInterpolation(value / duration);
+    }
+
+    @Override
+    protected void onPull(int delta) {
+        boolean layer = false;
+        int count = 2;
+        if (delta == 0 && mPullValue == 0) return;
+        if (delta == 0 && mPullValue != 0) {
+            // reset
+            for (int i = 0; i < count; i++) {
+                View child = mContentView.getChildAt((mPullValue < 0)
+                        ? i
+                        : mContentView.getChildCount() - 1 - i);
+                if (child == null) break;
+                ObjectAnimator trans = ObjectAnimator.ofFloat(child,
+                        mHorizontal ? "translationX" : "translationY",
+                                mHorizontal ? getTranslationX() : getTranslationY(),
+                                0);
+                ObjectAnimator rot = ObjectAnimator.ofFloat(child,
+                        mHorizontal ? "rotationY" : "rotationX",
+                                mHorizontal ? getRotationY() : getRotationX(),
+                                0);
+                AnimatorSet set = new AnimatorSet();
+                set.playTogether(trans, rot);
+                set.setDuration(100);
+                set.start();
+            }
+            mPullValue = 0;
+        } else {
+            if (mPullValue == 0) {
+                layer = true;
+            }
+            mPullValue += delta;
+        }
+        final int height = mHorizontal ? getWidth() : getHeight();
+        int oscroll = Math.abs(mPullValue);
+        int factor = (mPullValue <= 0) ? 1 : -1;
+        for (int i = 0; i < count; i++) {
+            View child = mContentView.getChildAt((mPullValue < 0)
+                    ? i
+                    : mContentView.getChildCount() - 1 - i);
+            if (child == null) break;
+            if (layer) {
+            }
+            float k = PULL_FACTOR[i];
+            float rot = -factor * ease(mCubic, oscroll, 0, k * 2, height);
+            int y =  factor * (int) ease(mCubic, oscroll, 0, k*20, height);
+            if (mHorizontal) {
+                child.setTranslationX(y);
+            } else {
+                child.setTranslationY(y);
+            }
+            if (mHorizontal) {
+                child.setRotationY(-rot);
+            } else {
+                child.setRotationX(rot);
+            }
+        }
+    }
+
+    static class ContentLayout extends LinearLayout {
+
+        NavTabScroller mScroller;
+
+        public ContentLayout(Context context, NavTabScroller scroller) {
+            super(context);
+            mScroller = scroller;
+        }
+
+        @Override
+        protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+            super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+            if (mScroller.getGap() > 0) {
+                View v = getChildAt(0);
+                if (v != null) {
+                    if (mScroller.isHorizontal()) {
+                        int total = v.getMeasuredWidth() + getMeasuredWidth();
+                        setMeasuredDimension(total, getMeasuredHeight());
+                    } else {
+                        int total = v.getMeasuredHeight() + getMeasuredHeight();
+                        setMeasuredDimension(getMeasuredWidth(), total);
+                    }
+                }
+
+            }
+        }
+
+    }
+
+}
\ No newline at end of file
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 61acef5..4772ff1 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -36,7 +36,6 @@
 import android.view.View;
 import android.view.ViewGroup;
 import android.view.accessibility.AccessibilityEvent;
-import android.view.animation.DecelerateInterpolator;
 import android.webkit.WebView;
 import android.widget.FrameLayout;
 import android.widget.ImageView;
@@ -90,7 +89,7 @@
     @Override
     public boolean onBackKey() {
         if (mNavScreen != null) {
-            mNavScreen.close();
+            mNavScreen.close(mUiController.getTabControl().getCurrentPosition());
             return true;
         }
         return super.onBackKey();
@@ -191,7 +190,7 @@
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (mNavScreen != null) {
-            hideNavScreen(false);
+            hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
         }
         return false;
     }
@@ -278,7 +277,7 @@
     @Override
     public void showWeb(boolean animate) {
         super.showWeb(animate);
-        hideNavScreen(animate);
+        hideNavScreen(mUiController.getTabControl().getCurrentPosition(), animate);
     }
 
     void showNavScreen() {
@@ -292,20 +291,20 @@
         mCustomViewContainer.addView(animView, COVER_SCREEN_PARAMS);
         mCustomViewContainer.setVisibility(View.VISIBLE);
         mCustomViewContainer.bringToFront();
-        View target = ((NavTabView) mNavScreen.mScroller.getSelectedView()).mImage;
         int fromLeft = 0;
         int fromTop = getTitleBar().getHeight();
         int fromRight = mContentView.getWidth();
         int fromBottom = mContentView.getHeight();
-        int width = target.getWidth();
-        int height = target.getHeight();
+        int width = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_width);
+        int height = mActivity.getResources().getDimensionPixelSize(R.dimen.nav_tab_height);
         int toLeft = (mContentView.getWidth() - width) / 2;
-        int toTop = fromTop + (mContentView.getHeight() - fromTop - height) / 2;
+        int toTop = ((fromBottom - (fromTop + height)) / 2 + fromTop);
         int toRight = toLeft + width;
         int toBottom = toTop + height;
         float scaleFactor = width / (float) mContentView.getWidth();
         detachTab(mActiveTab);
         mContentView.setVisibility(View.GONE);
+        AnimatorSet set1 = new AnimatorSet();
         AnimatorSet inanim = new AnimatorSet();
         ObjectAnimator tx = ObjectAnimator.ofInt(ascreen.mContent, "left",
                 fromLeft, toLeft);
@@ -317,12 +316,14 @@
                 fromBottom, toBottom);
         ObjectAnimator title = ObjectAnimator.ofFloat(ascreen.mTitle, "alpha",
                 1f, 0f);
-        ObjectAnimator content = ObjectAnimator.ofFloat(ascreen.mContent, "alpha",
-                1f, 0f);
         ObjectAnimator sx = ObjectAnimator.ofFloat(ascreen, "scaleFactor",
                 1f, scaleFactor);
-        inanim.playTogether(tx, ty, tr, tb, title, content, sx);
-        inanim.addListener(new AnimatorListenerAdapter() {
+        ObjectAnimator blend1 = ObjectAnimator.ofFloat(ascreen.mMain, "alpha", 1, 0);
+        blend1.setDuration(100);
+
+        inanim.playTogether(tx, ty, tr, tb, sx, title);
+        inanim.setDuration(200);
+        set1.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator anim) {
                 mCustomViewContainer.removeView(animView);
@@ -330,9 +331,8 @@
                 mUiController.setBlockEvents(false);
             }
         });
-        inanim.setInterpolator(new DecelerateInterpolator(2f));
-        inanim.setDuration(300);
-        inanim.start();
+        set1.playSequentially(inanim, blend1);
+        set1.start();
     }
 
     private void finishAnimationIn() {
@@ -343,9 +343,9 @@
         }
     }
 
-    void hideNavScreen(boolean animate) {
+    void hideNavScreen(int position, boolean animate) {
         if (mNavScreen == null) return;
-        final Tab tab = mNavScreen.getSelectedTab();
+        final Tab tab = mUiController.getTabControl().getTab(position);
         if ((tab == null) || !animate) {
             if (tab != null) {
                 setActiveTab(tab);
@@ -357,7 +357,7 @@
             finishAnimateOut();
             return;
         }
-        NavTabView tabview = (NavTabView) mNavScreen.getSelectedTabView();
+        NavTabView tabview = (NavTabView) mNavScreen.getTabView(position);
         if (tabview == null) {
             if (mTabControl.getTabCount() > 0) {
                 // use a fallback tab
@@ -371,23 +371,36 @@
         mUiController.setActiveTab(tab);
         mContentView.setVisibility(View.VISIBLE);
         final AnimScreen screen = new AnimScreen(mActivity, tab.getScreenshot());
-        View target = ((NavTabView) mNavScreen.mScroller.getSelectedView()).mImage;
+        mCustomViewContainer.addView(screen.mMain, COVER_SCREEN_PARAMS);
+        screen.mMain.layout(0, 0, mContentView.getWidth(),
+                mContentView.getHeight());
+        mNavScreen.mScroller.finishScroller();
+        ImageView target = tabview.mImage;
         int toLeft = 0;
         int toTop = getTitleBar().getHeight();
         int toRight = mContentView.getWidth();
-        int width = target.getWidth();
-        int height = target.getHeight();
-        int[] pos = new int[2];
-        tabview.mImage.getLocationInWindow(pos);
-        int fromLeft = pos[0];
-        int fromTop = pos[1];
+        int width = target.getDrawable().getIntrinsicWidth();
+        int height = target.getDrawable().getIntrinsicHeight();
+        int fromLeft = tabview.getLeft() + target.getLeft() - mNavScreen.mScroller.getScrollX();
+        int fromTop = tabview.getTop() + target.getTop() - mNavScreen.mScroller.getScrollY();
         int fromRight = fromLeft + width;
         int fromBottom = fromTop + height;
         float scaleFactor = mContentView.getWidth() / (float) width;
-        int toBottom = (int) (height * scaleFactor);
-        screen.mMain.setAlpha(0f);
-        mCustomViewContainer.addView(screen.mMain, COVER_SCREEN_PARAMS);
-        AnimatorSet animSet = new AnimatorSet();
+        int toBottom = toTop + (int) (height * scaleFactor);
+        ObjectAnimator l1 = ObjectAnimator.ofInt(screen.mContent, "left",
+                fromLeft, fromLeft);
+        ObjectAnimator t1 = ObjectAnimator.ofInt(screen.mContent, "top",
+                fromTop, fromTop);
+        ObjectAnimator r1 = ObjectAnimator.ofInt(screen.mContent, "right",
+                fromRight, fromRight);
+        ObjectAnimator b1 = ObjectAnimator.ofInt(screen.mContent, "bottom",
+                fromBottom, fromBottom);
+        AnimatorSet set1 = new AnimatorSet();
+        ObjectAnimator fade2 = ObjectAnimator.ofFloat(screen.mMain, "alpha", 0f, 1f);
+        ObjectAnimator fade1 = ObjectAnimator.ofFloat(mNavScreen, "alpha", 1f, 0f);
+        set1.playTogether(l1, t1, r1, b1, fade1, fade2);
+        set1.setDuration(100);
+        AnimatorSet set2 = new AnimatorSet();
         ObjectAnimator l = ObjectAnimator.ofInt(screen.mContent, "left",
                 fromLeft, toLeft);
         ObjectAnimator t = ObjectAnimator.ofInt(screen.mContent, "top",
@@ -398,11 +411,13 @@
                 fromBottom, toBottom);
         ObjectAnimator scale = ObjectAnimator.ofFloat(screen, "scaleFactor",
                 1f, scaleFactor);
-        ObjectAnimator alpha = ObjectAnimator.ofFloat(screen.mMain, "alpha", 1f, 1f);
         ObjectAnimator otheralpha = ObjectAnimator.ofFloat(mCustomViewContainer, "alpha", 1f, 0f);
-        alpha.setStartDelay(100);
-        animSet.playTogether(l, t, r, b, scale, alpha, otheralpha);
-        animSet.addListener(new AnimatorListenerAdapter() {
+        otheralpha.setDuration(100);
+        set2.playTogether(l, t, r, b, scale);
+        set2.setDuration(200);
+        AnimatorSet combo = new AnimatorSet();
+        combo.playSequentially(set1, set2, otheralpha);
+        combo.addListener(new AnimatorListenerAdapter() {
             @Override
             public void onAnimationEnd(Animator anim) {
                 mCustomViewContainer.removeView(screen.mMain);
@@ -410,8 +425,7 @@
                 mUiController.setBlockEvents(false);
             }
         });
-        animSet.setDuration(250);
-        animSet.start();
+        combo.start();
     }
 
     private void finishAnimateOut() {
@@ -431,7 +445,7 @@
         if (mNavScreen == null) {
             showNavScreen();
         } else {
-            hideNavScreen(false);
+            hideNavScreen(mUiController.getTabControl().getCurrentPosition(), false);
         }
     }
 
@@ -477,6 +491,8 @@
         public AnimScreen(Context ctx, Bitmap image) {
             mMain = LayoutInflater.from(ctx).inflate(R.layout.anim_screen,
                     null);
+            mTitle = (ImageView) mMain.findViewById(R.id.title);
+            mTitle.setVisibility(View.GONE);
             mContent = (ImageView) mMain.findViewById(R.id.content);
             mContent.setImageBitmap(image);
             mContent.setScaleType(ImageView.ScaleType.MATRIX);
diff --git a/src/com/android/browser/Tab.java b/src/com/android/browser/Tab.java
index 8c9dc02..96920a4 100644
--- a/src/com/android/browser/Tab.java
+++ b/src/com/android/browser/Tab.java
@@ -32,7 +32,10 @@
 import android.graphics.BitmapFactory;
 import android.graphics.Canvas;
 import android.graphics.Color;
+import android.graphics.Paint;
 import android.graphics.Picture;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
 import android.net.Uri;
 import android.net.http.SslError;
 import android.os.Bundle;
@@ -66,8 +69,6 @@
 import android.webkit.WebView.PictureListener;
 import android.webkit.WebViewClient;
 import android.widget.CheckBox;
-import android.widget.LinearLayout;
-import android.widget.TextView;
 import android.widget.Toast;
 
 import com.android.browser.TabControl.OnThumbnailUpdatedListener;
@@ -105,6 +106,12 @@
 
     private static Bitmap sDefaultFavicon;
 
+    private static Paint sAlphaPaint = new Paint();
+    static {
+        sAlphaPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
+        sAlphaPaint.setColor(Color.TRANSPARENT);
+    }
+
     public enum LockIcon {
         LOCK_ICON_UNSECURE,
         LOCK_ICON_SECURE,
@@ -2050,6 +2057,7 @@
         Canvas c = new Canvas(mCapture);
         final int left = mMainView.getScrollX();
         final int top = mMainView.getScrollY() + mMainView.getVisibleTitleHeight();
+        int state = c.save();
         c.translate(-left, -top);
         float scale = mCaptureWidth / (float) mMainView.getWidth();
         c.scale(scale, scale, left, top);
@@ -2058,6 +2066,14 @@
         } else {
             mMainView.draw(c);
         }
+        c.restoreToCount(state);
+        // manually anti-alias the edges for the tilt
+        c.drawRect(0, 0, 1, mCapture.getHeight(), sAlphaPaint);
+        c.drawRect(mCapture.getWidth() - 1, 0, mCapture.getWidth(),
+                mCapture.getHeight(), sAlphaPaint);
+        c.drawRect(0, 0, mCapture.getWidth(), 1, sAlphaPaint);
+        c.drawRect(0, mCapture.getHeight() - 1, mCapture.getWidth(),
+                mCapture.getHeight(), sAlphaPaint);
         c.setBitmap(null);
         mHandler.removeMessages(MSG_CAPTURE);
         persistThumbnail();
diff --git a/src/com/android/browser/view/Gallery.java b/src/com/android/browser/view/Gallery.java
deleted file mode 100644
index 2e2c75f..0000000
--- a/src/com/android/browser/view/Gallery.java
+++ /dev/null
@@ -1,1531 +0,0 @@
-/*
- * Copyright (C) 2011 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.browser.view;
-
-import android.animation.Animator;
-import android.animation.AnimatorListenerAdapter;
-import android.animation.ObjectAnimator;
-import android.content.Context;
-import android.content.res.TypedArray;
-import android.database.DataSetObserver;
-import android.graphics.Rect;
-import android.util.AttributeSet;
-import android.util.Log;
-import android.util.SparseArray;
-import android.view.GestureDetector;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.MotionEvent;
-import android.view.SoundEffectConstants;
-import android.view.View;
-import android.view.ViewConfiguration;
-import android.view.ViewGroup;
-import android.view.animation.BounceInterpolator;
-import android.view.animation.DecelerateInterpolator;
-import android.view.animation.Transformation;
-import android.widget.BaseAdapter;
-import android.widget.LinearLayout;
-import android.widget.Scroller;
-
-import com.android.internal.R;
-
-public class Gallery extends ViewGroup implements
-        GestureDetector.OnGestureListener {
-
-    private static final String TAG = "Gallery";
-
-    private static final boolean localLOGV = false;
-
-    private static final int INVALID_POSITION = -1;
-
-    /**
-     * Duration in milliseconds from the start of a scroll during which we're
-     * unsure whether the user is scrolling or flinging.
-     */
-    private static final int SCROLL_TO_FLING_UNCERTAINTY_TIMEOUT = 250;
-    private static final int INVALID_POINTER = -1;
-
-    private boolean mInLayout;
-    private int mWidthMeasureSpec;
-    private int mHeightMeasureSpec;
-    private boolean mBlockLayoutRequests;
-
-    private Rect mTouchFrame;
-
-    private RecycleBin mRecycler;
-
-    protected boolean mHorizontal;
-    protected int mFirstPosition;
-    private int mItemCount;
-    private boolean mDataChanged;
-
-    protected BaseAdapter mAdapter;
-
-    private int mSelectedPosition;
-    private int mOldSelectedPosition;
-
-    private int mSpacing = 0;
-    private int mAnimationDuration = 400;
-    private float mUnselectedAlpha;
-    private int mLeftMost;
-    private int mRightMost;
-    private int mGravity;
-
-    private GestureDetector mGestureDetector;
-
-    protected int mDownTouchPosition;
-    protected View mDownTouchView;
-    private FlingRunnable mFlingRunnable = new FlingRunnable();
-
-    private OnItemSelectedListener mOnItemSelectedListener;
-    private SelectionNotifier mSelectionNotifier;
-
-    private int mGapPosition;
-    private int mGap;
-    private Animator mGapAnimator;
-
-    /**
-     * Sets mSuppressSelectionChanged = false. This is used to set it to false
-     * in the future. It will also trigger a selection changed.
-     */
-    private Runnable mDisableSuppressSelectionChangedRunnable = new Runnable() {
-        public void run() {
-            mSuppressSelectionChanged = false;
-            selectionChanged();
-        }
-    };
-
-    private boolean mShouldStopFling;
-    private View mSelectedChild;
-    private boolean mShouldCallbackDuringFling = true;
-    private boolean mShouldCallbackOnUnselectedItemClick = true;
-    private boolean mSuppressSelectionChanged;
-    private boolean mReceivedInvokeKeyDown;
-
-    /**
-     * If true, this onScroll is the first for this user's drag (remember, a
-     * drag sends many onScrolls).
-     */
-    private boolean mIsFirstScroll;
-
-    private boolean mIsBeingDragged;
-    protected boolean mIsOrthoDragged;
-
-    private int mActivePointerId = INVALID_POINTER;
-
-    private int mTouchSlop;
-
-    private float mLastMotionCoord;
-    private float mLastOrthoCoord;
-
-    private int mScrollValue;
-
-    public Gallery(Context context) {
-        this(context, null);
-    }
-
-    public Gallery(Context context, AttributeSet attrs) {
-        this(context, attrs, R.attr.galleryStyle);
-    }
-
-    public Gallery(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        mRecycler = new RecycleBin();
-        mGestureDetector = new GestureDetector(context, this);
-        mGestureDetector.setIsLongpressEnabled(true);
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                com.android.internal.R.styleable.Gallery, defStyle, 0);
-        int index = a.getInt(com.android.internal.R.styleable.Gallery_gravity,
-                -1);
-        if (index >= 0) {
-            setGravity(index);
-        }
-        int animationDuration = a.getInt(
-                com.android.internal.R.styleable.Gallery_animationDuration, -1);
-        if (animationDuration > 0) {
-            setAnimationDuration(animationDuration);
-        }
-        float unselectedAlpha = a.getFloat(
-                com.android.internal.R.styleable.Gallery_unselectedAlpha, 0.5f);
-        setUnselectedAlpha(unselectedAlpha);
-        mHorizontal = true;
-        a.recycle();
-        // We draw the selected item last (because otherwise the item to the
-        // right overlaps it)
-        mGroupFlags |= FLAG_USE_CHILD_DRAWING_ORDER;
-        mGroupFlags |= FLAG_SUPPORT_STATIC_TRANSFORMATIONS;
-        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
-        mTouchSlop = configuration.getScaledTouchSlop();
-        setFocusable(true);
-        setWillNotDraw(false);
-        mGapPosition = INVALID_POSITION;
-        mGap = 0;
-        // proguard
-        setGap(getGap());
-        setScrollValue(getScrollValue());
-    }
-
-    /**
-     * Interface definition for a callback to be invoked when an item in this
-     * view has been selected.
-     */
-    public interface OnItemSelectedListener {
-        void onItemSelected(ViewGroup parent, View view, int position, long id);
-    }
-
-    public interface OnScrollFinishedListener {
-        void onScrollFinished();
-    }
-
-    /**
-     * Register a callback to be invoked when an item in this AdapterView has
-     * been selected.
-     *
-     * @param listener
-     *            The callback that will run
-     */
-    public void setOnItemSelectedListener(OnItemSelectedListener listener) {
-        mOnItemSelectedListener = listener;
-    }
-
-    public final OnItemSelectedListener getOnItemSelectedListener() {
-        return mOnItemSelectedListener;
-    }
-
-    public void setOrientation(int orientation) {
-        mHorizontal = (orientation == LinearLayout.HORIZONTAL);
-        requestLayout();
-    }
-
-    /**
-     * define a visual gap in the list of items
-     * the gap is rendered in front (left or above)
-     * the given position
-     * @param position
-     * @param gap
-     */
-    public void setGapPosition(int position, int gap) {
-        mGapPosition = position;
-        mGap = gap;
-    }
-
-    public void setGap(int gap) {
-        if (mGapPosition != INVALID_POSITION) {
-            mGap = gap;
-            layout(0, false);
-        }
-    }
-
-    public int getGap() {
-        return mGap;
-    }
-
-    public void setAdapter(BaseAdapter adapter, int selpos) {
-        mSelectedPosition = selpos;
-        setAdapter(adapter);
-    }
-
-    public void setAdapter(BaseAdapter adapter) {
-        mAdapter = adapter;
-        if (mAdapter != null) {
-            mAdapter.registerDataSetObserver(new DataSetObserver() {
-                @Override
-                public void onChanged() {
-                    super.onChanged();
-                    mDataChanged = true;
-                    handleDataChanged();
-                }
-
-                @Override
-                public void onInvalidated() {
-                    super.onInvalidated();
-                }
-            });
-        }
-        handleDataChanged();
-    }
-
-    public void handleDataChanged() {
-        if (mAdapter != null) {
-            if (mGapAnimator != null) {
-                mGapAnimator.cancel();
-            }
-            resetList();
-            mItemCount = mAdapter.getCount();
-            // checkFocus();
-            if (mItemCount > 0) {
-                int position = 0;
-                if (mSelectedPosition >= 0) {
-                    position = Math.min(mItemCount - 1, mSelectedPosition);
-                }
-                setSelectedPositionInt(position);
-                if (mGapPosition > INVALID_POSITION) {
-                    mGapAnimator = ObjectAnimator.ofInt(this, "gap", mGap, 0);
-                    mGapAnimator.setDuration(250);
-                    mGapAnimator.addListener(new AnimatorListenerAdapter() {
-                        @Override
-                        public void onAnimationEnd(Animator a) {
-                            mGapPosition = INVALID_POSITION;
-                            mGap = 0;
-                            mGapAnimator = null;
-                        }
-                    });
-                    mGapAnimator.start();
-                } else {
-                    layout(0, false);
-                }
-            }
-        } else {
-            // checkFocus();
-            mOldSelectedPosition = INVALID_POSITION;
-            setSelectedPositionInt(INVALID_POSITION);
-            resetList();
-            // Nothing selected
-            checkSelectionChanged();
-            invalidate();
-        }
-    }
-
-    /**
-     * Clear out all children from the list
-     */
-    void resetList() {
-        mDataChanged = false;
-        removeAllViewsInLayout();
-    }
-
-    public void setCallbackDuringFling(boolean shouldCallback) {
-        mShouldCallbackDuringFling = shouldCallback;
-    }
-
-    public void setCallbackOnUnselectedItemClick(boolean shouldCallback) {
-        mShouldCallbackOnUnselectedItemClick = shouldCallback;
-    }
-
-    public void setAnimationDuration(int animationDurationMillis) {
-        mAnimationDuration = animationDurationMillis;
-    }
-
-    public void setUnselectedAlpha(float unselectedAlpha) {
-        mUnselectedAlpha = unselectedAlpha;
-    }
-
-    @Override
-    protected boolean getChildStaticTransformation(View child, Transformation t) {
-        return false;
-    }
-
-    @Override
-    protected boolean checkLayoutParams(ViewGroup.LayoutParams p) {
-        return p instanceof LayoutParams;
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateLayoutParams(
-            ViewGroup.LayoutParams p) {
-        return new LayoutParams(p);
-    }
-
-    @Override
-    public ViewGroup.LayoutParams generateLayoutParams(AttributeSet attrs) {
-        return new LayoutParams(getContext(), attrs);
-    }
-
-    @Override
-    protected ViewGroup.LayoutParams generateDefaultLayoutParams() {
-        return new Gallery.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT,
-                ViewGroup.LayoutParams.WRAP_CONTENT);
-    }
-
-    @Override
-    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
-        int widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        int widthSize;
-        int heightSize;
-        if (mDataChanged) {
-            handleDataChanged();
-        }
-        int preferredHeight = 0;
-        int preferredWidth = 0;
-        boolean needsMeasuring = true;
-        int selectedPosition = getSelectedItemPosition();
-        if (selectedPosition >= 0 && mAdapter != null
-                && selectedPosition < mAdapter.getCount()) {
-            // Try looking in the recycler. (Maybe we were measured once
-            // already)
-            View view = mRecycler.get(selectedPosition);
-            if (view == null) {
-                // Make a new one
-                view = mAdapter.getView(selectedPosition, null, this);
-            }
-            if (view != null) {
-                // Put in recycler for re-measuring and/or layout
-                mRecycler.put(selectedPosition, view);
-            }
-            if (view != null) {
-                if (view.getLayoutParams() == null) {
-                    mBlockLayoutRequests = true;
-                    view.setLayoutParams(generateDefaultLayoutParams());
-                    mBlockLayoutRequests = false;
-                }
-                measureChild(view, widthMeasureSpec, heightMeasureSpec);
-                preferredHeight = getChildHeight(view);
-                preferredWidth = getChildWidth(view);
-                needsMeasuring = false;
-            }
-        }
-        if (needsMeasuring) {
-            // No views -- just use padding
-            preferredHeight = 0;
-            if (widthMode == MeasureSpec.UNSPECIFIED) {
-                preferredWidth = 0;
-            }
-        }
-        preferredHeight = Math
-                .max(preferredHeight, getSuggestedMinimumHeight());
-        preferredWidth = Math.max(preferredWidth, getSuggestedMinimumWidth());
-        heightSize = resolveSizeAndState(preferredHeight, heightMeasureSpec, 0);
-        widthSize = resolveSizeAndState(preferredWidth, widthMeasureSpec, 0);
-        setMeasuredDimension(widthSize, heightSize);
-        mHeightMeasureSpec = heightMeasureSpec;
-        mWidthMeasureSpec = widthMeasureSpec;
-    }
-
-    @Override
-    public void requestLayout() {
-        if (!mBlockLayoutRequests) {
-            super.requestLayout();
-        }
-    }
-
-    @Override
-    protected void onLayout(boolean changed, int l, int t, int r, int b) {
-        mInLayout = true;
-        layout(0, false);
-        mInLayout = false;
-    }
-
-    int getChildHeight(View child) {
-        return child.getMeasuredHeight();
-    }
-
-    int getChildWidth(View child) {
-        return child.getMeasuredWidth();
-    }
-
-    /**
-     * Tracks a motion scroll. In reality, this is used to do just about any
-     * movement to items (touch scroll, arrow-key scroll, set an item as
-     * selected).
-     *
-     * @param deltaX
-     *            Change in X from the previous event.
-     */
-    protected void trackMotionScroll(int deltaX) {
-        if (getChildCount() == 0) {
-            return;
-        }
-        boolean toLeft = deltaX < 0;
-        int limitedDeltaX = mFlingRunnable.mScroller.isFinished()
-                ? deltaX : getLimitedMotionScrollAmount(toLeft, deltaX);
-        if (limitedDeltaX != deltaX) {
-            // The above call returned a limited amount, so stop any
-            // scrolls/flings
-            mFlingRunnable.endFling(false);
-            onFinishedMovement();
-        }
-        offsetChildrenLeftAndRight(limitedDeltaX);
-        detachOffScreenChildren(toLeft);
-        if (toLeft) {
-            // If moved left, there will be empty space on the right
-            fillToGalleryRight();
-        } else {
-            // Similarly, empty space on the left
-            fillToGalleryLeft();
-        }
-        setSelectionToCenterChild();
-        invalidate();
-    }
-
-    int getLimitedMotionScrollAmount(boolean motionToLeft, int deltaX) {
-        int extremeItemPosition = motionToLeft ? mItemCount - 1 : 0;
-        View extremeChild = getChildAt(extremeItemPosition - mFirstPosition);
-        if (extremeChild == null) {
-            return deltaX;
-        }
-        int extremeChildCenter = getCenterOfView(extremeChild);
-        int galleryCenter = getCenterOfGallery();
-        if (motionToLeft) {
-            if (extremeChildCenter <= galleryCenter) {
-                return 0;
-            }
-        } else {
-            if (extremeChildCenter >= galleryCenter) {
-                return 0;
-            }
-        }
-        int centerDifference = galleryCenter - extremeChildCenter;
-        return motionToLeft ? Math.max(centerDifference, deltaX) : Math.min(
-                centerDifference, deltaX);
-    }
-
-    /**
-     * Offset the horizontal location of all children of this view by the
-     * specified number of pixels.
-     *
-     * @param offset
-     *            the number of pixels to offset
-     */
-    private void offsetChildrenLeftAndRight(int offset) {
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            if (mHorizontal) {
-                getChildAt(i).offsetLeftAndRight(offset);
-            } else {
-                getChildAt(i).offsetTopAndBottom(offset);
-            }
-        }
-    }
-
-    /**
-     * @return The center of this Gallery.
-     */
-    private int getCenterOfGallery() {
-        return (mHorizontal ? (getWidth() - mPaddingLeft - mPaddingRight) / 2
-                + mPaddingLeft : (getHeight() - mPaddingTop - mPaddingBottom)
-                / 2 + mPaddingTop);
-    }
-
-    /**
-     * @return The center of the given view.
-     */
-    private int getCenterOfView(View view) {
-        return (mHorizontal ? view.getLeft() + view.getWidth() / 2 : view
-                .getTop() + view.getHeight() / 2);
-    }
-
-    /**
-     * Detaches children that are off the screen (i.e.: Gallery bounds).
-     *
-     * @param toLeft
-     *            Whether to detach children to the left of the Gallery, or to
-     *            the right.
-     */
-    private void detachOffScreenChildren(boolean toLeft) {
-        int numChildren = getChildCount();
-        int firstPosition = mFirstPosition;
-        int start = 0;
-        int count = 0;
-        if (toLeft) {
-            final int galleryLeft = (mHorizontal ? mPaddingLeft : mPaddingTop);
-            for (int i = 0; i < numChildren; i++) {
-                final View child = getChildAt(i);
-                if ((mHorizontal && (child.getRight() >= galleryLeft))
-                        || (!mHorizontal && (child.getBottom() >= galleryLeft))) {
-                    break;
-                } else {
-                    count++;
-                    mRecycler.put(firstPosition + i, child);
-                }
-            }
-        } else {
-            final int galleryRight = (mHorizontal ? getWidth() - mPaddingRight
-                    : getHeight() - mPaddingBottom);
-            for (int i = numChildren - 1; i >= 0; i--) {
-                final View child = getChildAt(i);
-                if ((mHorizontal && (child.getLeft() <= galleryRight))
-                        || (!mHorizontal && (child.getTop() <= galleryRight))) {
-                    break;
-                } else {
-                    start = i;
-                    count++;
-                    mRecycler.put(firstPosition + i, child);
-                }
-            }
-        }
-        detachViewsFromParent(start, count);
-        if (toLeft) {
-            mFirstPosition += count;
-        }
-    }
-
-    private void scrollIntoSlots() {
-        if (getChildCount() == 0 || mSelectedChild == null)
-            return;
-        int selectedCenter = getCenterOfView(mSelectedChild);
-        int targetCenter = getCenterOfGallery();
-        int scrollAmount = targetCenter - selectedCenter;
-        if (scrollAmount != 0) {
-            mFlingRunnable.startUsingDistance(scrollAmount);
-        } else {
-            onFinishedMovement();
-        }
-    }
-
-    private void onFinishedMovement() {
-        if (mSuppressSelectionChanged) {
-            mSuppressSelectionChanged = false;
-            // We haven't sent callbacks during the fling, so do it now
-            selectionChanged();
-        }
-        invalidate();
-    }
-
-    protected void setSelectionToCenterChild() {
-        if (mSelectedChild == null)
-            return;
-        int galleryCenter = getCenterOfGallery();
-        int lastDistance = Integer.MAX_VALUE;
-        int newSelectedChildIndex = 0;
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            View child = getChildAt(i);
-            int distance = Math.abs(getCenterOfView(child) - galleryCenter);
-            if (distance > lastDistance) {
-                // we're moving away from the center, done
-                break;
-            } else {
-                newSelectedChildIndex = i;
-                lastDistance = distance;
-            }
-        }
-        int newPos = mFirstPosition + newSelectedChildIndex;
-        if (newPos != mSelectedPosition) {
-            setSelectedPositionInt(newPos);
-            checkSelectionChanged();
-        }
-    }
-
-    /**
-     * Creates and positions all views for this Gallery.
-     * <p>
-     * We layout rarely, most of the time {@link #trackMotionScroll(int)} takes
-     * care of repositioning, adding, and removing children.
-     *
-     * @param delta
-     *            Change in the selected position. +1 means the selection is
-     *            moving to the right, so views are scrolling to the left. -1
-     *            means the selection is moving to the left.
-     */
-    void layout(int delta, boolean animate) {
-        int childrenLeft = 0;
-        int childrenWidth = (mHorizontal ? mRight - mLeft : mBottom - mTop);
-        if (mDataChanged) {
-            handleDataChanged();
-        }
-        if (mItemCount == 0) {
-            mOldSelectedPosition = INVALID_POSITION;
-            setSelectedPositionInt(INVALID_POSITION);
-            resetList();
-            return;
-        }
-        if (mSelectedPosition >= 0) {
-            setSelectedPositionInt(mSelectedPosition);
-        }
-        recycleAllViews();
-        detachAllViewsFromParent();
-        mRightMost = 0;
-        mLeftMost = 0;
-        mFirstPosition = mSelectedPosition;
-        View sel = makeAndAddView(mSelectedPosition, 0, 0, true);
-        // Put the selected child in the center
-        int selectedOffset = childrenLeft + (childrenWidth / 2)
-                - (mHorizontal ? (sel.getWidth() / 2) : (sel.getHeight() / 2));
-        if (mHorizontal) {
-            sel.offsetLeftAndRight(selectedOffset);
-        } else {
-            sel.offsetTopAndBottom(selectedOffset);
-        }
-        fillToGalleryRight();
-        fillToGalleryLeft();
-        if (mGapPosition > INVALID_POSITION) {
-            adjustGap();
-        }
-        mRecycler.clear();
-        invalidate();
-        checkSelectionChanged();
-        mDataChanged = false;
-        updateSelectedItemMetadata();
-    }
-
-    void adjustGap() {
-        for (int i = 0; i < getChildCount(); i++) {
-            int pos = i + mFirstPosition;
-            if (pos >= mGapPosition) {
-                if (mHorizontal) {
-                    getChildAt(i).offsetLeftAndRight(mGap);
-                } else {
-                    getChildAt(i).offsetTopAndBottom(mGap);
-                }
-            }
-        }
-    }
-
-    void recycleAllViews() {
-        final int childCount = getChildCount();
-        final RecycleBin recycleBin = mRecycler;
-        final int position = mFirstPosition;
-        for (int i = 0; i < childCount; i++) {
-            View v = getChildAt(i);
-            int index = position + i;
-            recycleBin.put(index, v);
-        }
-    }
-
-    private void fillToGalleryLeft() {
-        int itemSpacing = mSpacing;
-        int galleryLeft = mHorizontal ? mPaddingLeft : mPaddingTop;
-        View prevIterationView = getChildAt(0);
-        int curPosition;
-        int curRightEdge;
-        if (prevIterationView != null) {
-            curPosition = mFirstPosition - 1;
-            curRightEdge = (mHorizontal ? prevIterationView.getLeft()
-                    : prevIterationView.getTop()) - itemSpacing;
-        } else {
-            // No children available!
-            curPosition = 0;
-            curRightEdge = (mHorizontal ? mRight - mLeft - mPaddingRight
-                    : mBottom - mTop - mPaddingBottom);
-            mShouldStopFling = true;
-        }
-        while (curRightEdge > galleryLeft && curPosition >= 0) {
-            prevIterationView = makeAndAddView(curPosition, curPosition
-                    - mSelectedPosition, curRightEdge, false);
-            // Remember some state
-            mFirstPosition = curPosition;
-            // Set state for next iteration
-            curRightEdge = (mHorizontal ? prevIterationView.getLeft()
-                    - itemSpacing : prevIterationView.getTop() - itemSpacing);
-            curPosition--;
-        }
-    }
-
-    private void fillToGalleryRight() {
-        int itemSpacing = mSpacing;
-        int galleryRight = (mHorizontal ? mRight - mLeft - mPaddingRight
-                : mBottom - mTop - mPaddingBottom);
-        int numChildren = getChildCount();
-        int numItems = mItemCount;
-        View prevIterationView = getChildAt(numChildren - 1);
-        int curPosition;
-        int curLeftEdge;
-        if (prevIterationView != null) {
-            curPosition = mFirstPosition + numChildren;
-            curLeftEdge = mHorizontal ? prevIterationView.getRight()
-                    + itemSpacing : prevIterationView.getBottom() + itemSpacing;
-        } else {
-            mFirstPosition = curPosition = mItemCount - 1;
-            curLeftEdge = mHorizontal ? mPaddingLeft : mPaddingTop;
-            mShouldStopFling = true;
-        }
-        while (curLeftEdge < galleryRight && curPosition < numItems) {
-            prevIterationView = makeAndAddView(curPosition, curPosition
-                    - mSelectedPosition, curLeftEdge, true);
-
-            // Set state for next iteration
-            curLeftEdge = mHorizontal ? prevIterationView.getRight()
-                    + itemSpacing : prevIterationView.getBottom() + itemSpacing;
-            curPosition++;
-        }
-    }
-
-    /**
-     * Obtain a view, either by pulling an existing view from the recycler or by
-     * getting a new one from the adapter. If we are animating, make sure there
-     * is enough information in the view's layout parameters to animate from the
-     * old to new positions.
-     *
-     * @param position
-     *            Position in the gallery for the view to obtain
-     * @param offset
-     *            Offset from the selected position
-     * @param x
-     *            X-coordintate indicating where this view should be placed.
-     *            This will either be the left or right edge of the view,
-     *            depending on the fromLeft paramter
-     * @param fromLeft
-     *            Are we positioning views based on the left edge? (i.e.,
-     *            building from left to right)?
-     * @return A view that has been added to the gallery
-     */
-    private View makeAndAddView(int position, int offset, int x,
-            boolean fromLeft) {
-        View child;
-        if (!mDataChanged) {
-            child = mRecycler.get(position);
-            if (child != null) {
-                // Can reuse an existing view
-                int childLeft = mHorizontal ? child.getLeft() : child.getTop();
-
-                // Remember left and right edges of where views have been placed
-                mRightMost = Math.max(mRightMost,
-                        childLeft
-                                + (mHorizontal ? child.getMeasuredWidth()
-                                        : child.getMeasuredHeight()));
-                mLeftMost = Math.min(mLeftMost, childLeft);
-
-                // Position the view
-                setUpChild(position, child, offset, x, fromLeft);
-
-                return child;
-            }
-        }
-        // Nothing found in the recycler -- ask the adapter for a view
-        child = mAdapter.getView(position, null, this);
-        // Position the view
-        setUpChild(position, child, offset, x, fromLeft);
-        return child;
-    }
-
-    /**
-     * Helper for makeAndAddView to set the position of a view and fill out its
-     * layout paramters.
-     *
-     * @param child
-     *            The view to position
-     * @param offset
-     *            Offset from the selected position
-     * @param x
-     *            X-coordintate indicating where this view should be placed.
-     *            This will either be the left or right edge of the view,
-     *            depending on the fromLeft paramter
-     * @param fromLeft
-     *            Are we positioning views based on the left edge? (i.e.,
-     *            building from left to right)?
-     */
-    private void setUpChild(int position, View child, int offset, int x,
-            boolean fromLeft) {
-        Gallery.LayoutParams lp = (Gallery.LayoutParams) child
-                .getLayoutParams();
-        if (lp == null) {
-            lp = (Gallery.LayoutParams) generateDefaultLayoutParams();
-        }
-        addViewInLayout(child, fromLeft ? -1 : 0, lp);
-        child.setSelected(offset == 0);
-        int childHeightSpec = ViewGroup.getChildMeasureSpec(mHeightMeasureSpec,
-                0, lp.height);
-        int childWidthSpec = ViewGroup.getChildMeasureSpec(mWidthMeasureSpec,
-                0, lp.width);
-        child.measure(childWidthSpec, childHeightSpec);
-        int childLeft;
-        int childRight;
-        // Position vertically based on gravity setting
-        int childTop = calculateTop(child, true);
-        int childBottom = childTop
-                + (mHorizontal ? child.getMeasuredHeight() : child
-                        .getMeasuredWidth());
-        int width = mHorizontal ? child.getMeasuredWidth() : child
-                .getMeasuredHeight();
-        if (fromLeft) {
-            childLeft = x;
-            childRight = childLeft + width;
-        } else {
-            childLeft = x - width;
-            childRight = x;
-        }
-        if (mHorizontal) {
-            child.layout(childLeft, childTop, childRight, childBottom);
-        } else {
-            child.layout(childTop, childLeft, childBottom, childRight);
-        }
-    }
-
-    /**
-     * Figure out vertical placement based on mGravity
-     *
-     * @param child
-     *            Child to place
-     * @return Where the top of the child should be
-     */
-    protected int calculateTop(View child, boolean duringLayout) {
-        int myHeight = mHorizontal ? (duringLayout ? getMeasuredHeight()
-                : getHeight()) : (duringLayout ? getMeasuredWidth()
-                : getWidth());
-        int childHeight = mHorizontal ? (duringLayout ? child
-                .getMeasuredHeight() : child.getHeight())
-                : (duringLayout ? child.getMeasuredWidth() : child.getWidth());
-        int childTop = 0;
-        switch (mGravity) {
-        case Gravity.TOP:
-        case Gravity.LEFT:
-            childTop = 0;
-            break;
-        case Gravity.CENTER_VERTICAL:
-        case Gravity.CENTER_HORIZONTAL:
-            int availableSpace = myHeight - childHeight;
-            childTop = availableSpace / 2;
-            break;
-        case Gravity.BOTTOM:
-        case Gravity.RIGHT:
-            childTop = myHeight - childHeight;
-            break;
-        }
-        return childTop;
-    }
-
-    @Override
-    public boolean onInterceptTouchEvent(MotionEvent ev) {
-        /*
-         * Shortcut the most recurring case: the user is in the dragging state
-         * and he is moving his finger. We want to intercept this motion.
-         */
-        final int action = ev.getAction();
-        if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
-            return true;
-        }
-        if ((action == MotionEvent.ACTION_MOVE) && (mIsOrthoDragged)) {
-            return true;
-        }
-        switch (action & MotionEvent.ACTION_MASK) {
-        case MotionEvent.ACTION_MOVE: {
-            /*
-             * mIsBeingDragged == false, otherwise the shortcut would have
-             * caught it. Check whether the user has moved far enough from his
-             * original down touch.
-             */
-            final int activePointerId = mActivePointerId;
-            if (activePointerId == INVALID_POINTER) {
-                // If we don't have a valid id, the touch down wasn't on
-                // content.
-                break;
-            }
-            final int pointerIndex = ev.findPointerIndex(activePointerId);
-            final float coord = mHorizontal ? ev.getX(pointerIndex) : ev
-                    .getY(pointerIndex);
-
-            final int diff = (int) Math.abs(coord - mLastMotionCoord);
-            if (diff > mTouchSlop) {
-                mIsBeingDragged = true;
-                mLastMotionCoord = coord;
-            } else {
-                final float ocoord = mHorizontal ? ev.getY(pointerIndex)
-                        : ev.getX(pointerIndex);
-                if (Math.abs(ocoord - mLastOrthoCoord) > mTouchSlop) {
-                    mIsOrthoDragged = true;
-                    mLastOrthoCoord = ocoord;
-                }
-            }
-            if (mIsBeingDragged || mIsOrthoDragged) {
-                if (mParent != null)
-                    mParent.requestDisallowInterceptTouchEvent(true);
-            }
-            break;
-        }
-        case MotionEvent.ACTION_DOWN: {
-            final float coord = mHorizontal ? ev.getX() : ev.getY();
-            /*
-             * Remember location of down touch. ACTION_DOWN always refers to
-             * pointer index 0.
-             */
-            mLastMotionCoord = coord;
-            mActivePointerId = ev.getPointerId(0);
-            /*
-             * If being flinged and user touches the screen, initiate drag;
-             * otherwise don't. mScroller.isFinished should be false when being
-             * flinged.
-             */
-            mIsBeingDragged = !mFlingRunnable.mScroller.isFinished();
-            mIsOrthoDragged = false;
-            final float ocoord = mHorizontal ? ev.getY() : ev.getX();
-            mLastOrthoCoord = ocoord;
-            mGestureDetector.onTouchEvent(ev);
-            break;
-        }
-        case MotionEvent.ACTION_CANCEL:
-        case MotionEvent.ACTION_UP:
-            /* Release the drag */
-            mIsBeingDragged = false;
-            mIsOrthoDragged = false;
-            mActivePointerId = INVALID_POINTER;
-            break;
-        case MotionEvent.ACTION_POINTER_DOWN: {
-            final int index = ev.getActionIndex();
-            mLastMotionCoord = mHorizontal ? ev.getX(index) : ev.getY(index);
-            mLastOrthoCoord = mHorizontal ? ev.getY(index) : ev.getX(index);
-            mActivePointerId = ev.getPointerId(index);
-            break;
-        }
-        case MotionEvent.ACTION_POINTER_UP:
-            mLastMotionCoord = mHorizontal ? ev.getX(ev.findPointerIndex(mActivePointerId))
-                    : ev.getY(ev.findPointerIndex(mActivePointerId));
-            mLastOrthoCoord = mHorizontal ? ev.getY(ev.findPointerIndex(mActivePointerId))
-                    : ev.getX(ev.findPointerIndex(mActivePointerId));
-            break;
-        }
-        return mIsBeingDragged || mIsOrthoDragged;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent event) {
-        // Give everything to the gesture detector
-        boolean retValue = mGestureDetector.onTouchEvent(event);
-        int action = event.getAction();
-        if (action == MotionEvent.ACTION_UP) {
-            // Helper method for lifted finger
-            onUp(mDownTouchView);
-        } else if (action == MotionEvent.ACTION_CANCEL) {
-            onCancel();
-        }
-        return retValue;
-    }
-
-    public boolean onSingleTapUp(MotionEvent e) {
-        if (mDownTouchPosition >= 0) {
-            // An item tap should make it selected, so scroll to this child.
-            scrollToChild(mDownTouchPosition - mFirstPosition);
-            if (mShouldCallbackOnUnselectedItemClick
-                    || mDownTouchPosition == mSelectedPosition) {
-                performItemClick(mDownTouchView, mDownTouchPosition,
-                        mAdapter.getItemId(mDownTouchPosition));
-            }
-            return true;
-        }
-        return false;
-    }
-
-    public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,
-            float velocityY) {
-        if (!mShouldCallbackDuringFling) {
-            removeCallbacks(mDisableSuppressSelectionChangedRunnable);
-            if (!mSuppressSelectionChanged)
-                mSuppressSelectionChanged = true;
-        }
-        if (isOrthoMove(velocityX, velocityY)) {
-            onOrthoFling(mDownTouchView, e1, e2, mHorizontal ? velocityY : velocityX);
-            return true;
-        }
-        mFlingRunnable.startUsingVelocity(mHorizontal ? (int) -velocityX
-                : (int) -velocityY);
-        return true;
-    }
-
-    public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,
-            float distanceY) {
-        if (localLOGV)
-            Log.v(TAG, String.valueOf(e2.getX() - e1.getX()));
-        mParent.requestDisallowInterceptTouchEvent(true);
-        if (mIsOrthoDragged && isOrthoMove(distanceX, distanceY)) {
-            onOrthoDrag(mDownTouchView, e1, e2, mHorizontal ? distanceY : distanceX);
-        } else if (mIsBeingDragged) {
-            if (!mShouldCallbackDuringFling) {
-                if (mIsFirstScroll) {
-                    if (!mSuppressSelectionChanged) {
-                        mSuppressSelectionChanged = true;
-                    }
-                    postDelayed(mDisableSuppressSelectionChangedRunnable,
-                            SCROLL_TO_FLING_UNCERTAINTY_TIMEOUT);
-                }
-            } else {
-                if (mSuppressSelectionChanged) {
-                    mSuppressSelectionChanged = false;
-                }
-            }
-            trackMotionScroll(mHorizontal ? -1 * (int) distanceX : -1
-                                            * (int) distanceY);
-
-            mIsFirstScroll = false;
-        }
-        return true;
-    }
-
-    protected void onOrthoDrag(View draggedView, MotionEvent down,
-            MotionEvent move, float distance) {
-    }
-
-    protected void onOrthoFling(View draggedView, MotionEvent down,
-            MotionEvent move, float velocity) {
-    }
-
-    public boolean onDown(MotionEvent e) {
-        mFlingRunnable.stop(false);
-        mDownTouchPosition = pointToPosition((int) e.getX(), (int) e.getY());
-        if (mDownTouchPosition >= 0) {
-            mDownTouchView = getChildAt(mDownTouchPosition - mFirstPosition);
-        }
-        // Reset the multiple-scroll tracking state
-        mIsFirstScroll = true;
-        // Must return true to get matching events for this down event.
-        return true;
-    }
-
-    /**
-     * Called when a touch event's action is MotionEvent.ACTION_UP.
-     */
-    protected void onUp(View downView) {
-        if (mFlingRunnable.mScroller.isFinished()) {
-            scrollIntoSlots();
-        }
-        dispatchUnpress();
-    }
-
-    private boolean isOrthoMove(float moveX, float moveY) {
-        return mHorizontal && Math.abs(moveY) > Math.abs(moveX)
-                || !mHorizontal && Math.abs(moveX) > Math.abs(moveY);
-    }
-
-    /**
-     * Called when a touch event's action is MotionEvent.ACTION_CANCEL.
-     */
-    void onCancel() {
-        onUp(mDownTouchView);
-    }
-
-    public void onLongPress(MotionEvent e) {
-    }
-
-    public void onShowPress(MotionEvent e) {
-    }
-
-    private void dispatchPress(View child) {
-        if (child != null) {
-            child.setPressed(true);
-        }
-        setPressed(true);
-    }
-
-    private void dispatchUnpress() {
-        for (int i = getChildCount() - 1; i >= 0; i--) {
-            getChildAt(i).setPressed(false);
-        }
-        setPressed(false);
-    }
-
-    @Override
-    public void dispatchSetSelected(boolean selected) {
-    }
-
-    @Override
-    protected void dispatchSetPressed(boolean pressed) {
-    }
-
-    @Override
-    public boolean dispatchKeyEvent(KeyEvent event) {
-        return event.dispatch(this, null, null);
-    }
-
-    /**
-     * Handles left, right, and clicking
-     *
-     * @see android.view.View#onKeyDown
-     */
-    @Override
-    public boolean onKeyDown(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-
-        case KeyEvent.KEYCODE_DPAD_LEFT:
-            if (movePrevious()) {
-                playSoundEffect(SoundEffectConstants.NAVIGATION_LEFT);
-            }
-            return true;
-
-        case KeyEvent.KEYCODE_DPAD_RIGHT:
-            if (moveNext()) {
-                playSoundEffect(SoundEffectConstants.NAVIGATION_RIGHT);
-            }
-            return true;
-
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-        case KeyEvent.KEYCODE_ENTER:
-            mReceivedInvokeKeyDown = true;
-            // fallthrough to default handling
-        }
-
-        return super.onKeyDown(keyCode, event);
-    }
-
-    @Override
-    public boolean onKeyUp(int keyCode, KeyEvent event) {
-        switch (keyCode) {
-        case KeyEvent.KEYCODE_DPAD_CENTER:
-        case KeyEvent.KEYCODE_ENTER: {
-
-            if (mReceivedInvokeKeyDown) {
-                if (mItemCount > 0) {
-
-                    dispatchPress(mSelectedChild);
-                    postDelayed(new Runnable() {
-                        public void run() {
-                            dispatchUnpress();
-                        }
-                    }, ViewConfiguration.getPressedStateDuration());
-
-                    int selectedIndex = mSelectedPosition - mFirstPosition;
-                    performItemClick(getChildAt(selectedIndex),
-                            mSelectedPosition,
-                            mAdapter.getItemId(mSelectedPosition));
-                }
-            }
-
-            // Clear the flag
-            mReceivedInvokeKeyDown = false;
-
-            return true;
-        }
-        }
-
-        return super.onKeyUp(keyCode, event);
-    }
-
-    private void performItemClick(View childAt, int mSelectedPosition2,
-            long itemId) {
-    }
-
-    protected boolean movePrevious() {
-        if (mItemCount > 0 && mSelectedPosition > 0) {
-            scrollToChild(mSelectedPosition - mFirstPosition - 1);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public boolean moveNext() {
-        if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) {
-            scrollToChild(mSelectedPosition - mFirstPosition + 1);
-            return true;
-        } else {
-            return false;
-        }
-    }
-
-    public boolean scrollToChild(int childPosition) {
-        View child = getChildAt(childPosition);
-        if (child != null) {
-            int distance = getCenterOfGallery() - getCenterOfView(child);
-            mFlingRunnable.startUsingDistance(distance, 0);
-            return true;
-        }
-        return false;
-    }
-
-    /**
-     * use the scroller to scroll to a new position, independent
-     * of whether attached or not
-     * this uses trackMotionScroll, which will set the selection
-     */
-    public void smoothScrollToPosition(int pos, int duration,
-            final OnScrollFinishedListener listener) {
-        if (pos >= mAdapter.getCount() || getChildCount() < 1) return;
-        int dist = (mSelectedPosition - pos) * (mHorizontal ? getChildHeight(getChildAt(0))
-                : getChildWidth(getChildAt(0)));
-        ObjectAnimator scroll = ObjectAnimator.ofInt(this, "scrollValue", 0, dist);
-        scroll.setDuration(duration);
-        scroll.addListener(new AnimatorListenerAdapter() {
-            @Override
-            public void onAnimationEnd(Animator animation) {
-                mScrollValue = 0;
-                listener.onScrollFinished();
-            }
-        });
-        scroll.setInterpolator(new BounceInterpolator());
-        scroll.start();
-    }
-
-    public void setScrollValue(int scroll) {
-        trackMotionScroll(scroll - mScrollValue);
-        mScrollValue = scroll;
-    }
-
-    public int getScrollValue() {
-        return mScrollValue;
-    }
-
-    protected void setSelectedPositionInt(int position) {
-        mSelectedPosition = position;
-        updateSelectedItemMetadata();
-    }
-
-    void checkSelectionChanged() {
-        if (mSelectedPosition != mOldSelectedPosition) {
-            selectionChanged();
-            mOldSelectedPosition = mSelectedPosition;
-        }
-    }
-
-    private class SelectionNotifier implements Runnable {
-        public void run() {
-            if (mDataChanged) {
-                // Data has changed between when this SelectionNotifier
-                // was posted and now. We need to wait until the AdapterView
-                // has been synched to the new data.
-                if (mAdapter != null) {
-                    post(this);
-                }
-            } else {
-                fireOnSelected();
-            }
-        }
-    }
-
-    void selectionChanged() {
-        if (mSuppressSelectionChanged)
-            return;
-        if (mOnItemSelectedListener != null) {
-            if (mInLayout || mBlockLayoutRequests) {
-                // If we are in a layout traversal, defer notification
-                if (mSelectionNotifier == null) {
-                    mSelectionNotifier = new SelectionNotifier();
-                }
-                post(mSelectionNotifier);
-            } else {
-                fireOnSelected();
-            }
-        }
-
-        // we fire selection events here not in View
-        // if (mSelectedPosition != ListView.INVALID_POSITION && isShown() &&
-        // !isInTouchMode()) {
-        // sendAccessibilityEvent(AccessibilityEvent.TYPE_VIEW_SELECTED);
-        // }
-    }
-
-    private void fireOnSelected() {
-        if (mOnItemSelectedListener == null)
-            return;
-
-        int selection = this.getSelectedItemPosition();
-        if (selection >= 0) {
-            View v = getSelectedView();
-            mOnItemSelectedListener.onItemSelected(this, v, selection,
-                    mAdapter.getItemId(selection));
-        }
-    }
-
-    public int getSelectedItemPosition() {
-        return mSelectedPosition;
-    }
-
-    public View getSelectedView() {
-        if (mItemCount > 0 && mSelectedPosition >= 0) {
-            return getChildAt(mSelectedPosition - mFirstPosition);
-        } else {
-            return null;
-        }
-    }
-
-    private void updateSelectedItemMetadata() {
-        View oldSelectedChild = mSelectedChild;
-        View child = mSelectedChild = getChildAt(mSelectedPosition
-                - mFirstPosition);
-        if (child == null) {
-            return;
-        }
-        child.setSelected(true);
-        child.setFocusable(true);
-
-        if (hasFocus()) {
-            child.requestFocus();
-        }
-        // We unfocus the old child down here so the above hasFocus check
-        // returns true
-        if (oldSelectedChild != null && oldSelectedChild != child) {
-            // Make sure its drawable state doesn't contain 'selected'
-            oldSelectedChild.setSelected(false);
-            // Make sure it is not focusable anymore, since otherwise arrow keys
-            // can make this one be focused
-            oldSelectedChild.setFocusable(false);
-        }
-    }
-
-    public void setGravity(int gravity) {
-        if (mGravity != gravity) {
-            mGravity = gravity;
-            requestLayout();
-        }
-    }
-
-    @Override
-    protected void onFocusChanged(boolean gainFocus, int direction,
-            Rect previouslyFocusedRect) {
-        super.onFocusChanged(gainFocus, direction, previouslyFocusedRect);
-        /*
-         * The gallery shows focus by focusing the selected item. So, give focus
-         * to our selected item instead. We steal keys from our selected item
-         * elsewhere.
-         */
-        if (gainFocus && mSelectedChild != null) {
-            mSelectedChild.requestFocus(direction);
-            mSelectedChild.setSelected(true);
-        }
-    }
-
-    void setNextSelectedPositionInt(int position) {
-        mSelectedPosition = position;
-    }
-
-    public int pointToPosition(int x, int y) {
-        Rect frame = mTouchFrame;
-        if (frame == null) {
-            mTouchFrame = new Rect();
-            frame = mTouchFrame;
-        }
-        final int count = getChildCount();
-        for (int i = count - 1; i >= 0; i--) {
-            View child = getChildAt(i);
-            if (child.getVisibility() == View.VISIBLE) {
-                child.getHitRect(frame);
-                if (frame.contains(x, y)) {
-                    return mFirstPosition + i;
-                }
-            }
-        }
-        return INVALID_POSITION;
-    }
-
-    private class FlingRunnable implements Runnable {
-        private Scroller mScroller;
-
-        /**
-         * X value reported by mScroller on the previous fling
-         */
-        private int mLastFlingX;
-
-        public FlingRunnable() {
-            mScroller = new Scroller(getContext());
-        }
-
-        private void startCommon() {
-            // Remove any pending flings
-            removeCallbacks(this);
-        }
-
-        public void startUsingVelocity(int initialVelocity) {
-            if (initialVelocity == 0)
-                return;
-            startCommon();
-            int initialX = initialVelocity < 0 ? Integer.MAX_VALUE : 0;
-            mLastFlingX = initialX;
-            mScroller.fling(initialX, 0, initialVelocity, 0, 0,
-                    Integer.MAX_VALUE, 0, Integer.MAX_VALUE);
-            post(this);
-        }
-
-        public void startUsingDistance(int distance) {
-            startUsingDistance(distance, mAnimationDuration);
-        }
-
-        public void startUsingDistance(int distance, int duration) {
-            if (distance == 0)
-                return;
-            startCommon();
-            mLastFlingX = 0;
-            mScroller.startScroll(0, 0, -distance, 0, duration);
-            post(this);
-        }
-
-        public void stop(boolean scrollIntoSlots) {
-            removeCallbacks(this);
-            endFling(scrollIntoSlots);
-        }
-
-        private void endFling(boolean scrollIntoSlots) {
-            mScroller.forceFinished(true);
-            if (scrollIntoSlots)
-                scrollIntoSlots();
-        }
-
-        public void run() {
-            if (mItemCount == 0) {
-                endFling(true);
-                return;
-            }
-            mShouldStopFling = false;
-            final Scroller scroller = mScroller;
-            boolean more = scroller.computeScrollOffset();
-            final int x = scroller.getCurrX();
-            // Flip sign to convert finger direction to list items direction
-            // (e.g. finger moving down means list is moving towards the top)
-            int delta = mLastFlingX - x;
-            // Pretend that each frame of a fling scroll is a touch scroll
-            if (delta > 0) {
-                // Moving towards the left. Use first view as mDownTouchPosition
-                mDownTouchPosition = mFirstPosition;
-                // Don't fling more than 1 screen
-                delta = mHorizontal ? Math.min(getWidth() - mPaddingLeft
-                        - mPaddingRight - 1, delta) : Math.min(getHeight()
-                        - mPaddingTop - mPaddingBottom - 1, delta);
-            } else {
-                // Moving towards the right. Use last view as mDownTouchPosition
-                int offsetToLast = getChildCount() - 1;
-                mDownTouchPosition = mFirstPosition + offsetToLast;
-                // Don't fling more than 1 screen
-                delta = mHorizontal ? Math.max(-(getWidth() - mPaddingRight
-                        - mPaddingLeft - 1), delta) : Math.max(-(getHeight()
-                        - mPaddingBottom - mPaddingTop - 1), delta);
-            }
-            trackMotionScroll(delta);
-            if (more && !mShouldStopFling) {
-                mLastFlingX = x;
-                post(this);
-            } else {
-                endFling(true);
-            }
-        }
-    }
-
-    /**
-     * Gallery extends LayoutParams to provide a place to hold current
-     * Transformation information along with previous position/transformation
-     * info.
-     *
-     */
-    public static class LayoutParams extends ViewGroup.LayoutParams {
-        public LayoutParams(Context c, AttributeSet attrs) {
-            super(c, attrs);
-        }
-
-        public LayoutParams(int w, int h) {
-            super(w, h);
-        }
-
-        public LayoutParams(ViewGroup.LayoutParams source) {
-            super(source);
-        }
-    }
-
-    class RecycleBin {
-        private final SparseArray<View> mScrapHeap = new SparseArray<View>();
-
-        public void put(int position, View v) {
-            mScrapHeap.put(position, v);
-        }
-
-        View get(int position) {
-            // System.out.print("Looking for " + position);
-            View result = mScrapHeap.get(position);
-            if (result != null) {
-                // System.out.println(" HIT");
-                mScrapHeap.delete(position);
-            } else {
-                // System.out.println(" MISS");
-            }
-            return result;
-        }
-
-        void clear() {
-            final SparseArray<View> scrapHeap = mScrapHeap;
-            final int count = scrapHeap.size();
-            for (int i = 0; i < count; i++) {
-                final View view = scrapHeap.valueAt(i);
-                if (view != null) {
-                    removeDetachedView(view, true);
-                }
-            }
-            scrapHeap.clear();
-        }
-    }
-
-}
diff --git a/src/com/android/browser/view/ScrollerView.java b/src/com/android/browser/view/ScrollerView.java
new file mode 100644
index 0000000..545dd25
--- /dev/null
+++ b/src/com/android/browser/view/ScrollerView.java
@@ -0,0 +1,1869 @@
+/*
+ * Copyright (C) 2006 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.browser.view;
+
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.StrictMode;
+import android.util.AttributeSet;
+import android.view.FocusFinder;
+import android.view.InputDevice;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.VelocityTracker;
+import android.view.View;
+import android.view.ViewConfiguration;
+import android.view.ViewDebug;
+import android.view.ViewGroup;
+import android.view.ViewParent;
+import android.view.accessibility.AccessibilityEvent;
+import android.view.accessibility.AccessibilityNodeInfo;
+import android.view.animation.AnimationUtils;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.OverScroller;
+import android.widget.TextView;
+
+import com.android.internal.R;
+
+import java.util.List;
+
+/**
+ * Layout container for a view hierarchy that can be scrolled by the user,
+ * allowing it to be larger than the physical display.  A ScrollView
+ * is a {@link FrameLayout}, meaning you should place one child in it
+ * containing the entire contents to scroll; this child may itself be a layout
+ * manager with a complex hierarchy of objects.  A child that is often used
+ * is a {@link LinearLayout} in a vertical orientation, presenting a vertical
+ * array of top-level items that the user can scroll through.
+ *
+ * <p>The {@link TextView} class also
+ * takes care of its own scrolling, so does not require a ScrollView, but
+ * using the two together is possible to achieve the effect of a text view
+ * within a larger container.
+ *
+ * <p>ScrollView only supports vertical scrolling.
+ *
+ * @attr ref android.R.styleable#ScrollView_fillViewport
+ */
+public class ScrollerView extends FrameLayout {
+    static final int ANIMATED_SCROLL_GAP = 250;
+
+    static final float MAX_SCROLL_FACTOR = 0.5f;
+
+    private long mLastScroll;
+
+    private final Rect mTempRect = new Rect();
+    protected OverScroller mScroller;
+
+    /**
+     * Position of the last motion event.
+     */
+    private float mLastMotionY;
+
+    /**
+     * True when the layout has changed but the traversal has not come through yet.
+     * Ideally the view hierarchy would keep track of this for us.
+     */
+    private boolean mIsLayoutDirty = true;
+
+    /**
+     * The child to give focus to in the event that a child has requested focus while the
+     * layout is dirty. This prevents the scroll from being wrong if the child has not been
+     * laid out before requesting focus.
+     */
+    protected View mChildToScrollTo = null;
+
+    /**
+     * True if the user is currently dragging this ScrollView around. This is
+     * not the same as 'is being flinged', which can be checked by
+     * mScroller.isFinished() (flinging begins when the user lifts his finger).
+     */
+    protected boolean mIsBeingDragged = false;
+
+    /**
+     * Determines speed during touch scrolling
+     */
+    private VelocityTracker mVelocityTracker;
+
+    /**
+     * When set to true, the scroll view measure its child to make it fill the currently
+     * visible area.
+     */
+    @ViewDebug.ExportedProperty(category = "layout")
+    private boolean mFillViewport;
+
+    /**
+     * Whether arrow scrolling is animated.
+     */
+    private boolean mSmoothScrollingEnabled = true;
+
+    private int mTouchSlop;
+    protected int mMinimumVelocity;
+    private int mMaximumVelocity;
+
+    private int mOverscrollDistance;
+    private int mOverflingDistance;
+
+    /**
+     * ID of the active pointer. This is used to retain consistency during
+     * drags/flings if multiple pointers are used.
+     */
+    private int mActivePointerId = INVALID_POINTER;
+
+    /**
+     * The StrictMode "critical time span" objects to catch animation
+     * stutters.  Non-null when a time-sensitive animation is
+     * in-flight.  Must call finish() on them when done animating.
+     * These are no-ops on user builds.
+     */
+    private StrictMode.Span mScrollStrictSpan = null;  // aka "drag"
+    private StrictMode.Span mFlingStrictSpan = null;
+
+    /**
+     * Sentinel value for no current active pointer.
+     * Used by {@link #mActivePointerId}.
+     */
+    private static final int INVALID_POINTER = -1;
+
+    /**
+     * orientation of the scrollview
+     */
+    protected boolean mHorizontal;
+
+    protected boolean mIsOrthoDragged;
+    private float mLastOrthoCoord;
+    private View mDownView;
+    private PointF mDownCoords;
+
+
+    public ScrollerView(Context context) {
+        this(context, null);
+    }
+
+    public ScrollerView(Context context, AttributeSet attrs) {
+        this(context, attrs, com.android.internal.R.attr.scrollViewStyle);
+    }
+
+    public ScrollerView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        initScrollView();
+
+        TypedArray a =
+            context.obtainStyledAttributes(attrs, com.android.internal.R.styleable.ScrollView, defStyle, 0);
+
+        setFillViewport(a.getBoolean(R.styleable.ScrollView_fillViewport, false));
+
+        a.recycle();
+    }
+
+    private void initScrollView() {
+        mScroller = new OverScroller(getContext());
+        setFocusable(true);
+        setDescendantFocusability(FOCUS_AFTER_DESCENDANTS);
+        setWillNotDraw(false);
+        final ViewConfiguration configuration = ViewConfiguration.get(mContext);
+        mTouchSlop = configuration.getScaledTouchSlop();
+        mMinimumVelocity = configuration.getScaledMinimumFlingVelocity();
+        mMaximumVelocity = configuration.getScaledMaximumFlingVelocity();
+        mOverscrollDistance = configuration.getScaledOverscrollDistance();
+        mOverflingDistance = configuration.getScaledOverflingDistance();
+        mDownCoords = new PointF();
+    }
+
+    public void setOrientation(int orientation) {
+        mHorizontal = (orientation == LinearLayout.HORIZONTAL);
+        requestLayout();
+    }
+
+    @Override
+    public boolean shouldDelayChildPressedState() {
+        return true;
+    }
+
+    @Override
+    protected float getTopFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        if (mHorizontal) {
+            final int length = getHorizontalFadingEdgeLength();
+            if (mScrollX < length) {
+                return mScrollX / (float) length;
+            }
+        } else {
+            final int length = getVerticalFadingEdgeLength();
+            if (mScrollY < length) {
+                return mScrollY / (float) length;
+            }
+        }
+        return 1.0f;
+    }
+
+    @Override
+    protected float getBottomFadingEdgeStrength() {
+        if (getChildCount() == 0) {
+            return 0.0f;
+        }
+        if (mHorizontal) {
+            final int length = getHorizontalFadingEdgeLength();
+            final int bottomEdge = getWidth() - mPaddingRight;
+            final int span = getChildAt(0).getRight() - mScrollX - bottomEdge;
+            if (span < length) {
+                return span / (float) length;
+            }
+        } else {
+            final int length = getVerticalFadingEdgeLength();
+            final int bottomEdge = getHeight() - mPaddingBottom;
+            final int span = getChildAt(0).getBottom() - mScrollY - bottomEdge;
+            if (span < length) {
+                return span / (float) length;
+            }
+        }
+        return 1.0f;
+    }
+
+    /**
+     * @return The maximum amount this scroll view will scroll in response to
+     *   an arrow event.
+     */
+    public int getMaxScrollAmount() {
+        return (int) (MAX_SCROLL_FACTOR * (mHorizontal
+                ? (mRight - mLeft) : (mBottom - mTop)));
+    }
+
+
+    @Override
+    public void addView(View child) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("ScrollView can host only one direct child");
+        }
+
+        super.addView(child);
+    }
+
+    @Override
+    public void addView(View child, int index) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("ScrollView can host only one direct child");
+        }
+
+        super.addView(child, index);
+    }
+
+    @Override
+    public void addView(View child, ViewGroup.LayoutParams params) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("ScrollView can host only one direct child");
+        }
+
+        super.addView(child, params);
+    }
+
+    @Override
+    public void addView(View child, int index, ViewGroup.LayoutParams params) {
+        if (getChildCount() > 0) {
+            throw new IllegalStateException("ScrollView can host only one direct child");
+        }
+
+        super.addView(child, index, params);
+    }
+
+    /**
+     * @return Returns true this ScrollView can be scrolled
+     */
+    private boolean canScroll() {
+        View child = getChildAt(0);
+        if (child != null) {
+            if (mHorizontal) {
+                return getWidth() < child.getWidth() + mPaddingLeft + mPaddingRight;
+            } else {
+                return getHeight() < child.getHeight() + mPaddingTop + mPaddingBottom;
+            }
+        }
+        return false;
+    }
+
+    /**
+     * Indicates whether this ScrollView's content is stretched to fill the viewport.
+     *
+     * @return True if the content fills the viewport, false otherwise.
+     *
+     * @attr ref android.R.styleable#ScrollView_fillViewport
+     */
+    public boolean isFillViewport() {
+        return mFillViewport;
+    }
+
+    /**
+     * Indicates this ScrollView whether it should stretch its content height to fill
+     * the viewport or not.
+     *
+     * @param fillViewport True to stretch the content's height to the viewport's
+     *        boundaries, false otherwise.
+     *
+     * @attr ref android.R.styleable#ScrollView_fillViewport
+     */
+    public void setFillViewport(boolean fillViewport) {
+        if (fillViewport != mFillViewport) {
+            mFillViewport = fillViewport;
+            requestLayout();
+        }
+    }
+
+    /**
+     * @return Whether arrow scrolling will animate its transition.
+     */
+    public boolean isSmoothScrollingEnabled() {
+        return mSmoothScrollingEnabled;
+    }
+
+    /**
+     * Set whether arrow scrolling will animate its transition.
+     * @param smoothScrollingEnabled whether arrow scrolling will animate its transition
+     */
+    public void setSmoothScrollingEnabled(boolean smoothScrollingEnabled) {
+        mSmoothScrollingEnabled = smoothScrollingEnabled;
+    }
+
+    @Override
+    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
+
+        if (!mFillViewport) {
+            return;
+        }
+
+        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
+        if (heightMode == MeasureSpec.UNSPECIFIED) {
+            return;
+        }
+
+        if (getChildCount() > 0) {
+            final View child = getChildAt(0);
+            if (mHorizontal) {
+                int width = getMeasuredWidth();
+                if (child.getMeasuredWidth() < width) {
+                    final FrameLayout.LayoutParams lp = (LayoutParams) child
+                            .getLayoutParams();
+
+                    int childHeightMeasureSpec = getChildMeasureSpec(
+                            heightMeasureSpec, mPaddingTop + mPaddingBottom,
+                            lp.height);
+                    width -= mPaddingLeft;
+                    width -= mPaddingRight;
+                    int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            width, MeasureSpec.EXACTLY);
+
+                    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+                }
+            } else {
+                int height = getMeasuredHeight();
+                if (child.getMeasuredHeight() < height) {
+                    final FrameLayout.LayoutParams lp = (LayoutParams) child
+                            .getLayoutParams();
+
+                    int childWidthMeasureSpec = getChildMeasureSpec(
+                            widthMeasureSpec, mPaddingLeft + mPaddingRight,
+                            lp.width);
+                    height -= mPaddingTop;
+                    height -= mPaddingBottom;
+                    int childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                            height, MeasureSpec.EXACTLY);
+
+                    child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+                }
+            }
+        }
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        // Let the focused view and/or our descendants get the key first
+        return super.dispatchKeyEvent(event) || executeKeyEvent(event);
+    }
+
+    /**
+     * You can call this function yourself to have the scroll view perform
+     * scrolling from a key event, just as if the event had been dispatched to
+     * it by the view hierarchy.
+     *
+     * @param event The key event to execute.
+     * @return Return true if the event was handled, else false.
+     */
+    public boolean executeKeyEvent(KeyEvent event) {
+        mTempRect.setEmpty();
+
+        if (!canScroll()) {
+            if (isFocused() && event.getKeyCode() != KeyEvent.KEYCODE_BACK) {
+                View currentFocused = findFocus();
+                if (currentFocused == this) currentFocused = null;
+                View nextFocused = FocusFinder.getInstance().findNextFocus(this,
+                        currentFocused, View.FOCUS_DOWN);
+                return nextFocused != null
+                        && nextFocused != this
+                        && nextFocused.requestFocus(View.FOCUS_DOWN);
+            }
+            return false;
+        }
+
+        boolean handled = false;
+        if (event.getAction() == KeyEvent.ACTION_DOWN) {
+            switch (event.getKeyCode()) {
+                case KeyEvent.KEYCODE_DPAD_UP:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_UP);
+                    } else {
+                        handled = fullScroll(View.FOCUS_UP);
+                    }
+                    break;
+                case KeyEvent.KEYCODE_DPAD_DOWN:
+                    if (!event.isAltPressed()) {
+                        handled = arrowScroll(View.FOCUS_DOWN);
+                    } else {
+                        handled = fullScroll(View.FOCUS_DOWN);
+                    }
+                    break;
+                case KeyEvent.KEYCODE_SPACE:
+                    pageScroll(event.isShiftPressed() ? View.FOCUS_UP : View.FOCUS_DOWN);
+                    break;
+            }
+        }
+
+        return handled;
+    }
+
+    private boolean inChild(int x, int y) {
+        if (getChildCount() > 0) {
+            final int scrollY = mScrollY;
+            final View child = getChildAt(0);
+            return !(y < child.getTop() - scrollY
+                    || y >= child.getBottom() - scrollY
+                    || x < child.getLeft()
+                    || x >= child.getRight());
+        }
+        return false;
+    }
+
+    private void initOrResetVelocityTracker() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        } else {
+            mVelocityTracker.clear();
+        }
+    }
+
+    private void initVelocityTrackerIfNotExists() {
+        if (mVelocityTracker == null) {
+            mVelocityTracker = VelocityTracker.obtain();
+        }
+    }
+
+    private void recycleVelocityTracker() {
+        if (mVelocityTracker != null) {
+            mVelocityTracker.recycle();
+            mVelocityTracker = null;
+        }
+    }
+
+    @Override
+    public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) {
+        if (disallowIntercept) {
+            recycleVelocityTracker();
+        }
+        super.requestDisallowInterceptTouchEvent(disallowIntercept);
+    }
+
+    @Override
+    public boolean onInterceptTouchEvent(MotionEvent ev) {
+        /*
+         * This method JUST determines whether we want to intercept the motion.
+         * If we return true, onMotionEvent will be called and we do the actual
+         * scrolling there.
+         */
+
+        /*
+         * Shortcut the most recurring case: the user is in the dragging state
+         * and he is moving his finger. We want to intercept this motion.
+         */
+        final int action = ev.getAction();
+        if ((action == MotionEvent.ACTION_MOVE) && (mIsBeingDragged)) {
+            return true;
+        }
+        if ((action == MotionEvent.ACTION_MOVE) && (mIsOrthoDragged)) {
+            return true;
+        }
+        switch (action & MotionEvent.ACTION_MASK) {
+        case MotionEvent.ACTION_MOVE: {
+            /*
+             * mIsBeingDragged == false, otherwise the shortcut would have
+             * caught it. Check whether the user has moved far enough from his
+             * original down touch.
+             */
+
+            /*
+             * Locally do absolute value. mLastMotionY is set to the y value of
+             * the down event.
+             */
+            final int activePointerId = mActivePointerId;
+            if (activePointerId == INVALID_POINTER) {
+                // If we don't have a valid id, the touch down wasn't on
+                // content.
+                break;
+            }
+
+            final int pointerIndex = ev.findPointerIndex(activePointerId);
+            final float y = mHorizontal ? ev.getX(pointerIndex) : ev
+                    .getY(pointerIndex);
+            final int yDiff = (int) Math.abs(y - mLastMotionY);
+            if (yDiff > mTouchSlop) {
+                mIsBeingDragged = true;
+                mLastMotionY = y;
+                initVelocityTrackerIfNotExists();
+                mVelocityTracker.addMovement(ev);
+                if (mScrollStrictSpan == null) {
+                    mScrollStrictSpan = StrictMode
+                            .enterCriticalSpan("ScrollView-scroll");
+                }
+            } else {
+                final float ocoord = mHorizontal ? ev.getY(pointerIndex) : ev
+                        .getX(pointerIndex);
+                if (Math.abs(ocoord - mLastOrthoCoord) > mTouchSlop) {
+                    mIsOrthoDragged = true;
+                    mLastOrthoCoord = ocoord;
+                    initVelocityTrackerIfNotExists();
+                    mVelocityTracker.addMovement(ev);
+                }
+            }
+            break;
+        }
+
+        case MotionEvent.ACTION_DOWN: {
+            final float y = mHorizontal ? ev.getX() : ev.getY();
+            mDownCoords.x = ev.getX();
+            mDownCoords.y = ev.getY();
+            if (!inChild((int) ev.getX(), (int) ev.getY())) {
+                mIsBeingDragged = false;
+                recycleVelocityTracker();
+                break;
+            }
+
+            /*
+             * Remember location of down touch. ACTION_DOWN always refers to
+             * pointer index 0.
+             */
+            mLastMotionY = y;
+            mActivePointerId = ev.getPointerId(0);
+
+            initOrResetVelocityTracker();
+            mVelocityTracker.addMovement(ev);
+            /*
+             * If being flinged and user touches the screen, initiate drag;
+             * otherwise don't. mScroller.isFinished should be false when being
+             * flinged.
+             */
+            mIsBeingDragged = !mScroller.isFinished();
+            if (mIsBeingDragged && mScrollStrictSpan == null) {
+                mScrollStrictSpan = StrictMode
+                        .enterCriticalSpan("ScrollView-scroll");
+            }
+            mIsOrthoDragged = false;
+            final float ocoord = mHorizontal ? ev.getY() : ev.getX();
+            mLastOrthoCoord = ocoord;
+            mDownView = findViewAt((int) ev.getX(), (int) ev.getY());
+            break;
+        }
+
+        case MotionEvent.ACTION_CANCEL:
+        case MotionEvent.ACTION_UP:
+            /* Release the drag */
+            mIsBeingDragged = false;
+            mIsOrthoDragged = false;
+            mActivePointerId = INVALID_POINTER;
+            recycleVelocityTracker();
+            if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0,
+                    getScrollRange())) {
+                invalidate();
+            }
+            break;
+        case MotionEvent.ACTION_POINTER_UP:
+            onSecondaryPointerUp(ev);
+            break;
+        }
+
+        /*
+         * The only time we want to intercept motion events is if we are in the
+         * drag mode.
+         */
+        return mIsBeingDragged || mIsOrthoDragged;
+    }
+
+    @Override
+    public boolean onTouchEvent(MotionEvent ev) {
+        initVelocityTrackerIfNotExists();
+        mVelocityTracker.addMovement(ev);
+
+        final int action = ev.getAction();
+        switch (action & MotionEvent.ACTION_MASK) {
+            case MotionEvent.ACTION_DOWN: {
+                mIsBeingDragged = getChildCount() != 0;
+                if (!mIsBeingDragged) {
+                    return false;
+                }
+
+                /*
+                 * If being flinged and user touches, stop the fling. isFinished
+                 * will be false if being flinged.
+                 */
+                if (!mScroller.isFinished()) {
+                    mScroller.abortAnimation();
+                    if (mFlingStrictSpan != null) {
+                        mFlingStrictSpan.finish();
+                        mFlingStrictSpan = null;
+                    }
+                }
+
+                // Remember where the motion event started
+                mLastMotionY = mHorizontal ? ev.getX() : ev.getY();
+                mActivePointerId = ev.getPointerId(0);
+                break;
+            }
+            case MotionEvent.ACTION_MOVE:
+                if (mIsOrthoDragged) {
+                    // Scroll to follow the motion event
+                    final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                    final float x = ev.getX(activePointerIndex);
+                    final float y = ev.getY(activePointerIndex);
+                    if (isOrthoMove(x - mDownCoords.x, y - mDownCoords.y)) {
+                        onOrthoDrag(mDownView, mHorizontal
+                                ? y - mDownCoords.y
+                                : x - mDownCoords.x);
+                    }
+                } else if (mIsBeingDragged) {
+                    // Scroll to follow the motion event
+                    final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
+                    final float y = mHorizontal ? ev.getX(activePointerIndex)
+                            : ev.getY(activePointerIndex);
+                    final int deltaY = (int) (mLastMotionY - y);
+                    mLastMotionY = y;
+
+                    final int oldX = mScrollX;
+                    final int oldY = mScrollY;
+                    final int range = getScrollRange();
+                    if (mHorizontal) {
+                        if (overScrollBy(deltaY, 0, mScrollX, 0, range, 0,
+                                mOverscrollDistance, 0, true)) {
+                            // Break our velocity if we hit a scroll barrier.
+                            mVelocityTracker.clear();
+                        }
+                    } else {
+                        if (overScrollBy(0, deltaY, 0, mScrollY, 0, range,
+                                0, mOverscrollDistance, true)) {
+                            // Break our velocity if we hit a scroll barrier.
+                            mVelocityTracker.clear();
+                        }
+                    }
+                    onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+
+                    final int overscrollMode = getOverScrollMode();
+                    if (overscrollMode == OVER_SCROLL_ALWAYS ||
+                            (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
+                        final int pulledToY = mHorizontal ? oldX + deltaY : oldY + deltaY;
+                        if (pulledToY < 0) {
+                            onPull(pulledToY);
+                        } else if (pulledToY > range) {
+                            onPull(pulledToY - range);
+                        } else {
+                            onPull(0);
+                        }
+                    }
+                }
+                break;
+            case MotionEvent.ACTION_UP:
+                final VelocityTracker vtracker = mVelocityTracker;
+                vtracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                if (isOrthoMove(vtracker.getXVelocity(mActivePointerId),
+                        vtracker.getYVelocity(mActivePointerId))
+                        && mMinimumVelocity < Math.abs((mHorizontal ? vtracker.getYVelocity()
+                                : vtracker.getXVelocity()))) {
+                    onOrthoFling(mDownView, mHorizontal ? vtracker.getYVelocity()
+                            : vtracker.getXVelocity());
+                    break;
+                }
+                if (mIsOrthoDragged) {
+                    onOrthoDragFinished(mDownView);
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                } else if (mIsBeingDragged) {
+                    final VelocityTracker velocityTracker = mVelocityTracker;
+                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
+                    int initialVelocity = mHorizontal
+                            ? (int) velocityTracker.getXVelocity(mActivePointerId)
+                            : (int) velocityTracker.getYVelocity(mActivePointerId);
+
+                    if (getChildCount() > 0) {
+                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
+                            fling(-initialVelocity);
+                        } else {
+                            final int bottom = getScrollRange();
+                            if (mHorizontal) {
+                                if (mScroller.springBack(mScrollX, mScrollY, 0, bottom, 0, 0)) {
+                                    invalidate();
+                                }
+                            } else {
+                                if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, bottom)) {
+                                    invalidate();
+                                }
+                            }
+                        }
+                        onPull(0);
+                    }
+
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                }
+                break;
+            case MotionEvent.ACTION_CANCEL:
+                if (mIsOrthoDragged) {
+                    onOrthoDragFinished(mDownView);
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                } else if (mIsBeingDragged && getChildCount() > 0) {
+                    if (mHorizontal) {
+                        if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
+                            invalidate();
+                        }
+                    } else {
+                        if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange())) {
+                            invalidate();
+                        }
+                    }
+                    mActivePointerId = INVALID_POINTER;
+                    endDrag();
+                }
+                break;
+            case MotionEvent.ACTION_POINTER_DOWN: {
+                final int index = ev.getActionIndex();
+                final float y = mHorizontal ? ev.getX(index) : ev.getY(index);
+                mLastMotionY = y;
+                mLastOrthoCoord = mHorizontal ? ev.getY(index) : ev.getX(index);
+                mActivePointerId = ev.getPointerId(index);
+                break;
+            }
+            case MotionEvent.ACTION_POINTER_UP:
+                onSecondaryPointerUp(ev);
+                mLastMotionY = mHorizontal
+                        ? ev.getX(ev.findPointerIndex(mActivePointerId))
+                        : ev.getY(ev.findPointerIndex(mActivePointerId));
+                break;
+        }
+        return true;
+    }
+
+    protected View findViewAt(int x, int y) {
+        // subclass responsibility
+        return null;
+    }
+
+    protected void onPull(int delta) {
+    }
+
+    private void onSecondaryPointerUp(MotionEvent ev) {
+        final int pointerIndex = (ev.getAction() & MotionEvent.ACTION_POINTER_INDEX_MASK) >>
+                MotionEvent.ACTION_POINTER_INDEX_SHIFT;
+        final int pointerId = ev.getPointerId(pointerIndex);
+        if (pointerId == mActivePointerId) {
+            // This was our active pointer going up. Choose a new
+            // active pointer and adjust accordingly.
+            // TODO: Make this decision more intelligent.
+            final int newPointerIndex = pointerIndex == 0 ? 1 : 0;
+            mLastMotionY = mHorizontal ? ev.getX(newPointerIndex) : ev.getY(newPointerIndex);
+            mActivePointerId = ev.getPointerId(newPointerIndex);
+            if (mVelocityTracker != null) {
+                mVelocityTracker.clear();
+            }
+            mLastOrthoCoord = mHorizontal ? ev.getY(newPointerIndex)
+                    : ev.getX(newPointerIndex);
+        }
+    }
+
+    @Override
+    public boolean onGenericMotionEvent(MotionEvent event) {
+        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
+            switch (event.getAction()) {
+            case MotionEvent.ACTION_SCROLL: {
+                if (!mIsBeingDragged) {
+                    if (mHorizontal) {
+                        final float hscroll = event
+                                .getAxisValue(MotionEvent.AXIS_HSCROLL);
+                        if (hscroll != 0) {
+                            final int delta = (int) (hscroll * getHorizontalScrollFactor());
+                            final int range = getScrollRange();
+                            int oldScrollX = mScrollX;
+                            int newScrollX = oldScrollX - delta;
+                            if (newScrollX < 0) {
+                                newScrollX = 0;
+                            } else if (newScrollX > range) {
+                                newScrollX = range;
+                            }
+                            if (newScrollX != oldScrollX) {
+                                super.scrollTo(newScrollX, mScrollY);
+                                return true;
+                            }
+                        }
+                    } else {
+                        final float vscroll = event
+                                .getAxisValue(MotionEvent.AXIS_VSCROLL);
+                        if (vscroll != 0) {
+                            final int delta = (int) (vscroll * getVerticalScrollFactor());
+                            final int range = getScrollRange();
+                            int oldScrollY = mScrollY;
+                            int newScrollY = oldScrollY - delta;
+                            if (newScrollY < 0) {
+                                newScrollY = 0;
+                            } else if (newScrollY > range) {
+                                newScrollY = range;
+                            }
+                            if (newScrollY != oldScrollY) {
+                                super.scrollTo(mScrollX, newScrollY);
+                                return true;
+                            }
+                        }
+                    }
+                }
+            }
+            }
+        }
+        return super.onGenericMotionEvent(event);
+    }
+
+    protected void onOrthoDrag(View draggedView, float distance) {
+    }
+
+    protected void onOrthoDragFinished(View draggedView) {
+    }
+
+    protected void onOrthoFling(View draggedView, float velocity) {
+    }
+
+    @Override
+    protected void onOverScrolled(int scrollX, int scrollY,
+            boolean clampedX, boolean clampedY) {
+        // Treat animating scrolls differently; see #computeScroll() for why.
+        if (!mScroller.isFinished()) {
+            mScrollX = scrollX;
+            mScrollY = scrollY;
+            invalidateParentIfNeeded();
+            if (mHorizontal && clampedX) {
+                mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
+            } else if (!mHorizontal && clampedY) {
+                mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
+            }
+        } else {
+            super.scrollTo(scrollX, scrollY);
+        }
+        awakenScrollBars();
+    }
+
+    @Override
+    public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) {
+        super.onInitializeAccessibilityNodeInfo(info);
+        info.setScrollable(true);
+    }
+
+    @Override
+    public void onInitializeAccessibilityEvent(AccessibilityEvent event) {
+        super.onInitializeAccessibilityEvent(event);
+        event.setScrollable(true);
+    }
+
+    @Override
+    public boolean dispatchPopulateAccessibilityEvent(AccessibilityEvent event) {
+        // Do not append text content to scroll events they are fired frequently
+        // and the client has already received another event type with the text.
+        if (event.getEventType() != AccessibilityEvent.TYPE_VIEW_SCROLLED) {
+            super.dispatchPopulateAccessibilityEvent(event);
+        }
+        return false;
+    }
+
+    private int getScrollRange() {
+        int scrollRange = 0;
+        if (getChildCount() > 0) {
+            View child = getChildAt(0);
+            if (mHorizontal) {
+                scrollRange = Math.max(0,
+                        child.getWidth() - (getWidth() - mPaddingRight - mPaddingLeft));
+            } else {
+                scrollRange = Math.max(0,
+                        child.getHeight() - (getHeight() - mPaddingBottom - mPaddingTop));
+            }
+        }
+        return scrollRange;
+    }
+
+    /**
+     * <p>
+     * Finds the next focusable component that fits in this View's bounds
+     * (excluding fading edges) pretending that this View's top is located at
+     * the parameter top.
+     * </p>
+     *
+     * @param topFocus           look for a candidate at the top of the bounds if topFocus is true,
+     *                           or at the bottom of the bounds if topFocus is false
+     * @param top                the top offset of the bounds in which a focusable must be
+     *                           found (the fading edge is assumed to start at this position)
+     * @param preferredFocusable the View that has highest priority and will be
+     *                           returned if it is within my bounds (null is valid)
+     * @return the next focusable component in the bounds or null if none can be found
+     */
+    private View findFocusableViewInMyBounds(final boolean topFocus,
+            final int top, View preferredFocusable) {
+        /*
+         * The fading edge's transparent side should be considered for focus
+         * since it's mostly visible, so we divide the actual fading edge length
+         * by 2.
+         */
+        final int fadingEdgeLength = (mHorizontal
+                ? getHorizontalFadingEdgeLength()
+                : getVerticalFadingEdgeLength()) / 2;
+        final int topWithoutFadingEdge = top + fadingEdgeLength;
+        final int bottomWithoutFadingEdge = top + (mHorizontal ? getWidth() : getHeight()) - fadingEdgeLength;
+
+        if ((preferredFocusable != null)
+                && ((mHorizontal ? preferredFocusable.getLeft() : preferredFocusable.getTop())
+                        < bottomWithoutFadingEdge)
+                && ((mHorizontal ? preferredFocusable.getRight() : preferredFocusable.getBottom()) > topWithoutFadingEdge)) {
+            return preferredFocusable;
+        }
+
+        return findFocusableViewInBounds(topFocus, topWithoutFadingEdge,
+                bottomWithoutFadingEdge);
+    }
+
+    /**
+     * <p>
+     * Finds the next focusable component that fits in the specified bounds.
+     * </p>
+     *
+     * @param topFocus look for a candidate is the one at the top of the bounds
+     *                 if topFocus is true, or at the bottom of the bounds if topFocus is
+     *                 false
+     * @param top      the top offset of the bounds in which a focusable must be
+     *                 found
+     * @param bottom   the bottom offset of the bounds in which a focusable must
+     *                 be found
+     * @return the next focusable component in the bounds or null if none can
+     *         be found
+     */
+    private View findFocusableViewInBounds(boolean topFocus, int top, int bottom) {
+
+        List<View> focusables = getFocusables(View.FOCUS_FORWARD);
+        View focusCandidate = null;
+
+        /*
+         * A fully contained focusable is one where its top is below the bound's
+         * top, and its bottom is above the bound's bottom. A partially
+         * contained focusable is one where some part of it is within the
+         * bounds, but it also has some part that is not within bounds.  A fully contained
+         * focusable is preferred to a partially contained focusable.
+         */
+        boolean foundFullyContainedFocusable = false;
+
+        int count = focusables.size();
+        for (int i = 0; i < count; i++) {
+            View view = focusables.get(i);
+            int viewTop = mHorizontal ? view.getLeft() : view.getTop();
+            int viewBottom = mHorizontal ? view.getRight() : view.getBottom();
+
+            if (top < viewBottom && viewTop < bottom) {
+                /*
+                 * the focusable is in the target area, it is a candidate for
+                 * focusing
+                 */
+
+                final boolean viewIsFullyContained = (top < viewTop) &&
+                        (viewBottom < bottom);
+
+                if (focusCandidate == null) {
+                    /* No candidate, take this one */
+                    focusCandidate = view;
+                    foundFullyContainedFocusable = viewIsFullyContained;
+                } else {
+                    final int ctop = mHorizontal ? focusCandidate.getLeft() : focusCandidate.getTop();
+                    final int cbot = mHorizontal ? focusCandidate.getRight() : focusCandidate.getBottom();
+                    final boolean viewIsCloserToBoundary =
+                            (topFocus && viewTop < ctop) ||
+                                    (!topFocus && viewBottom > cbot);
+
+                    if (foundFullyContainedFocusable) {
+                        if (viewIsFullyContained && viewIsCloserToBoundary) {
+                            /*
+                             * We're dealing with only fully contained views, so
+                             * it has to be closer to the boundary to beat our
+                             * candidate
+                             */
+                            focusCandidate = view;
+                        }
+                    } else {
+                        if (viewIsFullyContained) {
+                            /* Any fully contained view beats a partially contained view */
+                            focusCandidate = view;
+                            foundFullyContainedFocusable = true;
+                        } else if (viewIsCloserToBoundary) {
+                            /*
+                             * Partially contained view beats another partially
+                             * contained view if it's closer
+                             */
+                            focusCandidate = view;
+                        }
+                    }
+                }
+            }
+        }
+
+        return focusCandidate;
+    }
+
+    // i was here
+
+    /**
+     * <p>Handles scrolling in response to a "page up/down" shortcut press. This
+     * method will scroll the view by one page up or down and give the focus
+     * to the topmost/bottommost component in the new visible area. If no
+     * component is a good candidate for focus, this scrollview reclaims the
+     * focus.</p>
+     *
+     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+     *                  to go one page up or
+     *                  {@link android.view.View#FOCUS_DOWN} to go one page down
+     * @return true if the key event is consumed by this method, false otherwise
+     */
+    public boolean pageScroll(int direction) {
+        boolean down = direction == View.FOCUS_DOWN;
+        int height = getHeight();
+
+        if (down) {
+            mTempRect.top = getScrollY() + height;
+            int count = getChildCount();
+            if (count > 0) {
+                View view = getChildAt(count - 1);
+                if (mTempRect.top + height > view.getBottom()) {
+                    mTempRect.top = view.getBottom() - height;
+                }
+            }
+        } else {
+            mTempRect.top = getScrollY() - height;
+            if (mTempRect.top < 0) {
+                mTempRect.top = 0;
+            }
+        }
+        mTempRect.bottom = mTempRect.top + height;
+
+        return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom);
+    }
+
+    /**
+     * <p>Handles scrolling in response to a "home/end" shortcut press. This
+     * method will scroll the view to the top or bottom and give the focus
+     * to the topmost/bottommost component in the new visible area. If no
+     * component is a good candidate for focus, this scrollview reclaims the
+     * focus.</p>
+     *
+     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+     *                  to go the top of the view or
+     *                  {@link android.view.View#FOCUS_DOWN} to go the bottom
+     * @return true if the key event is consumed by this method, false otherwise
+     */
+    public boolean fullScroll(int direction) {
+        boolean down = direction == View.FOCUS_DOWN;
+        int height = getHeight();
+
+        mTempRect.top = 0;
+        mTempRect.bottom = height;
+
+        if (down) {
+            int count = getChildCount();
+            if (count > 0) {
+                View view = getChildAt(count - 1);
+                mTempRect.bottom = view.getBottom() + mPaddingBottom;
+                mTempRect.top = mTempRect.bottom - height;
+            }
+        }
+
+        return scrollAndFocus(direction, mTempRect.top, mTempRect.bottom);
+    }
+
+    /**
+     * <p>Scrolls the view to make the area defined by <code>top</code> and
+     * <code>bottom</code> visible. This method attempts to give the focus
+     * to a component visible in this area. If no component can be focused in
+     * the new visible area, the focus is reclaimed by this ScrollView.</p>
+     *
+     * @param direction the scroll direction: {@link android.view.View#FOCUS_UP}
+     *                  to go upward, {@link android.view.View#FOCUS_DOWN} to downward
+     * @param top       the top offset of the new area to be made visible
+     * @param bottom    the bottom offset of the new area to be made visible
+     * @return true if the key event is consumed by this method, false otherwise
+     */
+    private boolean scrollAndFocus(int direction, int top, int bottom) {
+        boolean handled = true;
+
+        int height = getHeight();
+        int containerTop = getScrollY();
+        int containerBottom = containerTop + height;
+        boolean up = direction == View.FOCUS_UP;
+
+        View newFocused = findFocusableViewInBounds(up, top, bottom);
+        if (newFocused == null) {
+            newFocused = this;
+        }
+
+        if (top >= containerTop && bottom <= containerBottom) {
+            handled = false;
+        } else {
+            int delta = up ? (top - containerTop) : (bottom - containerBottom);
+            doScrollY(delta);
+        }
+
+        if (newFocused != findFocus()) newFocused.requestFocus(direction);
+
+        return handled;
+    }
+
+    /**
+     * Handle scrolling in response to an up or down arrow click.
+     *
+     * @param direction The direction corresponding to the arrow key that was
+     *                  pressed
+     * @return True if we consumed the event, false otherwise
+     */
+    public boolean arrowScroll(int direction) {
+
+        View currentFocused = findFocus();
+        if (currentFocused == this) currentFocused = null;
+
+        View nextFocused = FocusFinder.getInstance().findNextFocus(this, currentFocused, direction);
+
+        final int maxJump = getMaxScrollAmount();
+
+        if (nextFocused != null && isWithinDeltaOfScreen(nextFocused, maxJump, getHeight())) {
+            nextFocused.getDrawingRect(mTempRect);
+            offsetDescendantRectToMyCoords(nextFocused, mTempRect);
+            int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+            doScrollY(scrollDelta);
+            nextFocused.requestFocus(direction);
+        } else {
+            // no new focus
+            int scrollDelta = maxJump;
+
+            if (direction == View.FOCUS_UP && getScrollY() < scrollDelta) {
+                scrollDelta = getScrollY();
+            } else if (direction == View.FOCUS_DOWN) {
+                if (getChildCount() > 0) {
+                    int daBottom = getChildAt(0).getBottom();
+                    int screenBottom = getScrollY() + getHeight() - mPaddingBottom;
+                    if (daBottom - screenBottom < maxJump) {
+                        scrollDelta = daBottom - screenBottom;
+                    }
+                }
+            }
+            if (scrollDelta == 0) {
+                return false;
+            }
+            doScrollY(direction == View.FOCUS_DOWN ? scrollDelta : -scrollDelta);
+        }
+
+        if (currentFocused != null && currentFocused.isFocused()
+                && isOffScreen(currentFocused)) {
+            // previously focused item still has focus and is off screen, give
+            // it up (take it back to ourselves)
+            // (also, need to temporarily force FOCUS_BEFORE_DESCENDANTS so we are
+            // sure to
+            // get it)
+            final int descendantFocusability = getDescendantFocusability();  // save
+            setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
+            requestFocus();
+            setDescendantFocusability(descendantFocusability);  // restore
+        }
+        return true;
+    }
+
+    private boolean isOrthoMove(float moveX, float moveY) {
+        return mHorizontal && Math.abs(moveY) > Math.abs(moveX)
+                || !mHorizontal && Math.abs(moveX) > Math.abs(moveY);
+    }
+
+    /**
+     * @return whether the descendant of this scroll view is scrolled off
+     *  screen.
+     */
+    private boolean isOffScreen(View descendant) {
+        if (mHorizontal) {
+            return !isWithinDeltaOfScreen(descendant, getWidth(), 0);
+        } else {
+            return !isWithinDeltaOfScreen(descendant, 0, getHeight());
+        }
+    }
+
+    /**
+     * @return whether the descendant of this scroll view is within delta
+     *  pixels of being on the screen.
+     */
+    private boolean isWithinDeltaOfScreen(View descendant, int delta, int height) {
+        descendant.getDrawingRect(mTempRect);
+        offsetDescendantRectToMyCoords(descendant, mTempRect);
+        if (mHorizontal) {
+            return (mTempRect.right + delta) >= getScrollX()
+            && (mTempRect.left - delta) <= (getScrollX() + height);
+        } else {
+            return (mTempRect.bottom + delta) >= getScrollY()
+            && (mTempRect.top - delta) <= (getScrollY() + height);
+        }
+    }
+
+    /**
+     * Smooth scroll by a Y delta
+     *
+     * @param delta the number of pixels to scroll by on the Y axis
+     */
+    private void doScrollY(int delta) {
+        if (delta != 0) {
+            if (mSmoothScrollingEnabled) {
+                if (mHorizontal) {
+                    smoothScrollBy(0, delta);
+                } else {
+                    smoothScrollBy(delta, 0);
+                }
+            } else {
+                if (mHorizontal) {
+                    scrollBy(0, delta);
+                } else {
+                    scrollBy(delta, 0);
+                }
+            }
+        }
+    }
+
+    /**
+     * Like {@link View#scrollBy}, but scroll smoothly instead of immediately.
+     *
+     * @param dx the number of pixels to scroll by on the X axis
+     * @param dy the number of pixels to scroll by on the Y axis
+     */
+    public final void smoothScrollBy(int dx, int dy) {
+        if (getChildCount() == 0) {
+            // Nothing to do.
+            return;
+        }
+        long duration = AnimationUtils.currentAnimationTimeMillis() - mLastScroll;
+        if (duration > ANIMATED_SCROLL_GAP) {
+            if (mHorizontal) {
+                final int width = getWidth() - mPaddingRight - mPaddingLeft;
+                final int right = getChildAt(0).getWidth();
+                final int maxX = Math.max(0, right - width);
+                final int scrollX = mScrollX;
+                dx = Math.max(0, Math.min(scrollX + dx, maxX)) - scrollX;
+                mScroller.startScroll(scrollX, mScrollY, dx, 0);
+            } else {
+                final int height = getHeight() - mPaddingBottom - mPaddingTop;
+                final int bottom = getChildAt(0).getHeight();
+                final int maxY = Math.max(0, bottom - height);
+                final int scrollY = mScrollY;
+                dy = Math.max(0, Math.min(scrollY + dy, maxY)) - scrollY;
+                mScroller.startScroll(mScrollX, scrollY, 0, dy);
+            }
+            invalidate();
+        } else {
+            if (!mScroller.isFinished()) {
+                mScroller.abortAnimation();
+                if (mFlingStrictSpan != null) {
+                    mFlingStrictSpan.finish();
+                    mFlingStrictSpan = null;
+                }
+            }
+            scrollBy(dx, dy);
+        }
+        mLastScroll = AnimationUtils.currentAnimationTimeMillis();
+    }
+
+    /**
+     * Like {@link #scrollTo}, but scroll smoothly instead of immediately.
+     *
+     * @param x the position where to scroll on the X axis
+     * @param y the position where to scroll on the Y axis
+     */
+    public final void smoothScrollTo(int x, int y) {
+        smoothScrollBy(x - mScrollX, y - mScrollY);
+    }
+
+    /**
+     * <p>
+     * The scroll range of a scroll view is the overall height of all of its
+     * children.
+     * </p>
+     */
+    @Override
+    protected int computeVerticalScrollRange() {
+        if (mHorizontal) {
+            return super.computeVerticalScrollRange();
+        }
+        final int count = getChildCount();
+        final int contentHeight = getHeight() - mPaddingBottom - mPaddingTop;
+        if (count == 0) {
+            return contentHeight;
+        }
+
+        int scrollRange = getChildAt(0).getBottom();
+        final int scrollY = mScrollY;
+        final int overscrollBottom = Math.max(0, scrollRange - contentHeight);
+        if (scrollY < 0) {
+            scrollRange -= scrollY;
+        } else if (scrollY > overscrollBottom) {
+            scrollRange += scrollY - overscrollBottom;
+        }
+
+        return scrollRange;
+    }
+
+    /**
+     * <p>
+     * The scroll range of a scroll view is the overall height of all of its
+     * children.
+     * </p>
+     */
+    @Override
+    protected int computeHorizontalScrollRange() {
+        if (!mHorizontal) {
+            return super.computeHorizontalScrollRange();
+        }
+        final int count = getChildCount();
+        final int contentWidth = getWidth() - mPaddingRight - mPaddingLeft;
+        if (count == 0) {
+            return contentWidth;
+        }
+
+        int scrollRange = getChildAt(0).getRight();
+        final int scrollX = mScrollX;
+        final int overscrollBottom = Math.max(0, scrollRange - contentWidth);
+        if (scrollX < 0) {
+            scrollRange -= scrollX;
+        } else if (scrollX > overscrollBottom) {
+            scrollRange += scrollX - overscrollBottom;
+        }
+
+        return scrollRange;
+    }
+
+    @Override
+    protected int computeVerticalScrollOffset() {
+        return Math.max(0, super.computeVerticalScrollOffset());
+    }
+
+    @Override
+    protected int computeHorizontalScrollOffset() {
+        return Math.max(0, super.computeHorizontalScrollOffset());
+    }
+
+    @Override
+    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
+        ViewGroup.LayoutParams lp = child.getLayoutParams();
+
+        int childWidthMeasureSpec;
+        int childHeightMeasureSpec;
+
+        if (mHorizontal) {
+            childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingTop
+                    + mPaddingBottom, lp.height);
+
+            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        } else {
+            childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec, mPaddingLeft
+                    + mPaddingRight, lp.width);
+
+            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED);
+        }
+
+        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+    }
+
+    @Override
+    protected void measureChildWithMargins(View child, int parentWidthMeasureSpec, int widthUsed,
+            int parentHeightMeasureSpec, int heightUsed) {
+        final MarginLayoutParams lp = (MarginLayoutParams) child.getLayoutParams();
+
+        int childWidthMeasureSpec;
+        int childHeightMeasureSpec;
+        if (mHorizontal) {
+            childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
+                    mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
+                            + heightUsed, lp.height);
+            childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
+                    lp.leftMargin + lp.rightMargin, MeasureSpec.UNSPECIFIED);
+        } else {
+            childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
+                    mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
+                            + widthUsed, lp.width);
+            childHeightMeasureSpec = MeasureSpec.makeMeasureSpec(
+                    lp.topMargin + lp.bottomMargin, MeasureSpec.UNSPECIFIED);
+        }
+        child.measure(childWidthMeasureSpec, childHeightMeasureSpec);
+    }
+
+    @Override
+    public void computeScroll() {
+        if (mScroller.computeScrollOffset()) {
+            // This is called at drawing time by ViewGroup.  We don't want to
+            // re-show the scrollbars at this point, which scrollTo will do,
+            // so we replicate most of scrollTo here.
+            //
+            //         It's a little odd to call onScrollChanged from inside the drawing.
+            //
+            //         It is, except when you remember that computeScroll() is used to
+            //         animate scrolling. So unless we want to defer the onScrollChanged()
+            //         until the end of the animated scrolling, we don't really have a
+            //         choice here.
+            //
+            //         I agree.  The alternative, which I think would be worse, is to post
+            //         something and tell the subclasses later.  This is bad because there
+            //         will be a window where mScrollX/Y is different from what the app
+            //         thinks it is.
+            //
+            int oldX = mScrollX;
+            int oldY = mScrollY;
+            int x = mScroller.getCurrX();
+            int y = mScroller.getCurrY();
+
+            if (oldX != x || oldY != y) {
+                if (mHorizontal) {
+                    overScrollBy(x - oldX, y - oldY, oldX, oldY, getScrollRange(), 0,
+                            mOverflingDistance, 0, false);
+                } else {
+                    overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, getScrollRange(),
+                            0, mOverflingDistance, false);
+                }
+                onScrollChanged(mScrollX, mScrollY, oldX, oldY);
+            }
+            awakenScrollBars();
+
+            // Keep on drawing until the animation has finished.
+            postInvalidate();
+        } else {
+            if (mFlingStrictSpan != null) {
+                mFlingStrictSpan.finish();
+                mFlingStrictSpan = null;
+            }
+        }
+    }
+
+    /**
+     * Scrolls the view to the given child.
+     *
+     * @param child the View to scroll to
+     */
+    private void scrollToChild(View child) {
+        child.getDrawingRect(mTempRect);
+
+        /* Offset from child's local coordinates to ScrollView coordinates */
+        offsetDescendantRectToMyCoords(child, mTempRect);
+        scrollToChildRect(mTempRect, true);
+    }
+
+    /**
+     * If rect is off screen, scroll just enough to get it (or at least the
+     * first screen size chunk of it) on screen.
+     *
+     * @param rect      The rectangle.
+     * @param immediate True to scroll immediately without animation
+     * @return true if scrolling was performed
+     */
+    private boolean scrollToChildRect(Rect rect, boolean immediate) {
+        final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
+        final boolean scroll = delta != 0;
+        if (scroll) {
+            if (immediate) {
+                if (mHorizontal) {
+                    scrollBy(delta, 0);
+                } else {
+                    scrollBy(0, delta);
+                }
+            } else {
+                if (mHorizontal) {
+                    smoothScrollBy(delta, 0);
+                } else {
+                    smoothScrollBy(0, delta);
+                }
+            }
+        }
+        return scroll;
+    }
+
+    /**
+     * Compute the amount to scroll in the Y direction in order to get
+     * a rectangle completely on the screen (or, if taller than the screen,
+     * at least the first screen size chunk of it).
+     *
+     * @param rect The rect.
+     * @return The scroll delta.
+     */
+    protected int computeScrollDeltaToGetChildRectOnScreen(Rect rect) {
+        if (mHorizontal) {
+            return computeScrollDeltaToGetChildRectOnScreenHorizontal(rect);
+        } else {
+            return computeScrollDeltaToGetChildRectOnScreenVertical(rect);
+        }
+    }
+
+    private int computeScrollDeltaToGetChildRectOnScreenVertical(Rect rect) {
+        if (getChildCount() == 0) return 0;
+
+        int height = getHeight();
+        int screenTop = getScrollY();
+        int screenBottom = screenTop + height;
+
+        int fadingEdge = getVerticalFadingEdgeLength();
+
+        // leave room for top fading edge as long as rect isn't at very top
+        if (rect.top > 0) {
+            screenTop += fadingEdge;
+        }
+
+        // leave room for bottom fading edge as long as rect isn't at very bottom
+        if (rect.bottom < getChildAt(0).getHeight()) {
+            screenBottom -= fadingEdge;
+        }
+
+        int scrollYDelta = 0;
+
+        if (rect.bottom > screenBottom && rect.top > screenTop) {
+            // need to move down to get it in view: move down just enough so
+            // that the entire rectangle is in view (or at least the first
+            // screen size chunk).
+
+            if (rect.height() > height) {
+                // just enough to get screen size chunk on
+                scrollYDelta += (rect.top - screenTop);
+            } else {
+                // get entire rect at bottom of screen
+                scrollYDelta += (rect.bottom - screenBottom);
+            }
+
+            // make sure we aren't scrolling beyond the end of our content
+            int bottom = getChildAt(0).getBottom();
+            int distanceToBottom = bottom - screenBottom;
+            scrollYDelta = Math.min(scrollYDelta, distanceToBottom);
+
+        } else if (rect.top < screenTop && rect.bottom < screenBottom) {
+            // need to move up to get it in view: move up just enough so that
+            // entire rectangle is in view (or at least the first screen
+            // size chunk of it).
+
+            if (rect.height() > height) {
+                // screen size chunk
+                scrollYDelta -= (screenBottom - rect.bottom);
+            } else {
+                // entire rect at top
+                scrollYDelta -= (screenTop - rect.top);
+            }
+
+            // make sure we aren't scrolling any further than the top our content
+            scrollYDelta = Math.max(scrollYDelta, -getScrollY());
+        }
+        return scrollYDelta;
+    }
+
+    private int computeScrollDeltaToGetChildRectOnScreenHorizontal(Rect rect) {
+        if (getChildCount() == 0) return 0;
+
+        int width = getWidth();
+        int screenLeft = getScrollX();
+        int screenRight = screenLeft + width;
+
+        int fadingEdge = getHorizontalFadingEdgeLength();
+
+        // leave room for left fading edge as long as rect isn't at very left
+        if (rect.left > 0) {
+            screenLeft += fadingEdge;
+        }
+
+        // leave room for right fading edge as long as rect isn't at very right
+        if (rect.right < getChildAt(0).getWidth()) {
+            screenRight -= fadingEdge;
+        }
+
+        int scrollXDelta = 0;
+
+        if (rect.right > screenRight && rect.left > screenLeft) {
+            // need to move right to get it in view: move right just enough so
+            // that the entire rectangle is in view (or at least the first
+            // screen size chunk).
+
+            if (rect.width() > width) {
+                // just enough to get screen size chunk on
+                scrollXDelta += (rect.left - screenLeft);
+            } else {
+                // get entire rect at right of screen
+                scrollXDelta += (rect.right - screenRight);
+            }
+
+            // make sure we aren't scrolling beyond the end of our content
+            int right = getChildAt(0).getRight();
+            int distanceToRight = right - screenRight;
+            scrollXDelta = Math.min(scrollXDelta, distanceToRight);
+
+        } else if (rect.left < screenLeft && rect.right < screenRight) {
+            // need to move right to get it in view: move right just enough so that
+            // entire rectangle is in view (or at least the first screen
+            // size chunk of it).
+
+            if (rect.width() > width) {
+                // screen size chunk
+                scrollXDelta -= (screenRight - rect.right);
+            } else {
+                // entire rect at left
+                scrollXDelta -= (screenLeft - rect.left);
+            }
+
+            // make sure we aren't scrolling any further than the left our content
+            scrollXDelta = Math.max(scrollXDelta, -getScrollX());
+        }
+        return scrollXDelta;
+    }
+
+
+    @Override
+    public void requestChildFocus(View child, View focused) {
+        if (!mIsLayoutDirty) {
+            scrollToChild(focused);
+        } else {
+            // The child may not be laid out yet, we can't compute the scroll yet
+            mChildToScrollTo = focused;
+        }
+        super.requestChildFocus(child, focused);
+    }
+
+
+    /**
+     * When looking for focus in children of a scroll view, need to be a little
+     * more careful not to give focus to something that is scrolled off screen.
+     *
+     * This is more expensive than the default {@link android.view.ViewGroup}
+     * implementation, otherwise this behavior might have been made the default.
+     */
+    @Override
+    protected boolean onRequestFocusInDescendants(int direction,
+            Rect previouslyFocusedRect) {
+
+        // convert from forward / backward notation to up / down / left / right
+        // (ugh).
+        if (mHorizontal) {
+            if (direction == View.FOCUS_FORWARD) {
+                direction = View.FOCUS_RIGHT;
+            } else if (direction == View.FOCUS_BACKWARD) {
+                direction = View.FOCUS_LEFT;
+            }
+        } else {
+            if (direction == View.FOCUS_FORWARD) {
+                direction = View.FOCUS_DOWN;
+            } else if (direction == View.FOCUS_BACKWARD) {
+                direction = View.FOCUS_UP;
+            }
+        }
+
+        final View nextFocus = previouslyFocusedRect == null ?
+                FocusFinder.getInstance().findNextFocus(this, null, direction) :
+                FocusFinder.getInstance().findNextFocusFromRect(this,
+                        previouslyFocusedRect, direction);
+
+        if (nextFocus == null) {
+            return false;
+        }
+
+        if (isOffScreen(nextFocus)) {
+            return false;
+        }
+
+        return nextFocus.requestFocus(direction, previouslyFocusedRect);
+    }
+
+    @Override
+    public boolean requestChildRectangleOnScreen(View child, Rect rectangle,
+            boolean immediate) {
+        // offset into coordinate space of this scroll view
+        rectangle.offset(child.getLeft() - child.getScrollX(),
+                child.getTop() - child.getScrollY());
+
+        return scrollToChildRect(rectangle, immediate);
+    }
+
+    @Override
+    public void requestLayout() {
+        mIsLayoutDirty = true;
+        super.requestLayout();
+    }
+
+    @Override
+    protected void onDetachedFromWindow() {
+        super.onDetachedFromWindow();
+
+        if (mScrollStrictSpan != null) {
+            mScrollStrictSpan.finish();
+            mScrollStrictSpan = null;
+        }
+        if (mFlingStrictSpan != null) {
+            mFlingStrictSpan.finish();
+            mFlingStrictSpan = null;
+        }
+    }
+
+    @Override
+    protected void onLayout(boolean changed, int l, int t, int r, int b) {
+        super.onLayout(changed, l, t, r, b);
+        mIsLayoutDirty = false;
+        // Give a child focus if it needs it
+        if (mChildToScrollTo != null && isViewDescendantOf(mChildToScrollTo, this)) {
+            scrollToChild(mChildToScrollTo);
+        }
+        mChildToScrollTo = null;
+
+        // Calling this with the present values causes it to re-clam them
+        scrollTo(mScrollX, mScrollY);
+    }
+
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        super.onSizeChanged(w, h, oldw, oldh);
+
+        View currentFocused = findFocus();
+        if (null == currentFocused || this == currentFocused)
+            return;
+
+        // If the currently-focused view was visible on the screen when the
+        // screen was at the old height, then scroll the screen to make that
+        // view visible with the new screen height.
+        if (isWithinDeltaOfScreen(currentFocused, 0, oldh)) {
+            currentFocused.getDrawingRect(mTempRect);
+            offsetDescendantRectToMyCoords(currentFocused, mTempRect);
+            int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
+            doScrollY(scrollDelta);
+        }
+    }
+
+    /**
+     * Return true if child is an descendant of parent, (or equal to the parent).
+     */
+    private boolean isViewDescendantOf(View child, View parent) {
+        if (child == parent) {
+            return true;
+        }
+
+        final ViewParent theParent = child.getParent();
+        return (theParent instanceof ViewGroup) && isViewDescendantOf((View) theParent, parent);
+    }
+
+    /**
+     * Fling the scroll view
+     *
+     * @param velocityY The initial velocity in the Y direction. Positive
+     *                  numbers mean that the finger/cursor is moving down the screen,
+     *                  which means we want to scroll towards the top.
+     */
+    public void fling(int velocityY) {
+        if (getChildCount() > 0) {
+            if (mHorizontal) {
+                int width = getWidth() - mPaddingRight - mPaddingLeft;
+                int right = getChildAt(0).getWidth();
+
+                mScroller.fling(mScrollX, mScrollY, velocityY, 0,
+                        0, Math.max(0, right - width), 0, 0, width/2, 0);
+            } else {
+                int height = getHeight() - mPaddingBottom - mPaddingTop;
+                int bottom = getChildAt(0).getHeight();
+
+                mScroller.fling(mScrollX, mScrollY, 0, velocityY, 0, 0, 0,
+                        Math.max(0, bottom - height), 0, height/2);
+            }
+            if (mFlingStrictSpan == null) {
+                mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
+            }
+
+            invalidate();
+        }
+    }
+
+    private void endDrag() {
+        mIsBeingDragged = false;
+        mIsOrthoDragged = false;
+        mDownView = null;
+        recycleVelocityTracker();
+        if (mScrollStrictSpan != null) {
+            mScrollStrictSpan.finish();
+            mScrollStrictSpan = null;
+        }
+    }
+
+    /**
+     * {@inheritDoc}
+     *
+     * <p>This version also clamps the scrolling to the bounds of our child.
+     */
+    @Override
+    public void scrollTo(int x, int y) {
+        // we rely on the fact the View.scrollBy calls scrollTo.
+        if (getChildCount() > 0) {
+            View child = getChildAt(0);
+            x = clamp(x, getWidth() - mPaddingRight - mPaddingLeft, child.getWidth());
+            y = clamp(y, getHeight() - mPaddingBottom - mPaddingTop, child.getHeight());
+            if (x != mScrollX || y != mScrollY) {
+                super.scrollTo(x, y);
+            }
+        }
+    }
+
+    private int clamp(int n, int my, int child) {
+        if (my >= child || n < 0) {
+            /* my >= child is this case:
+             *                    |--------------- me ---------------|
+             *     |------ child ------|
+             * or
+             *     |--------------- me ---------------|
+             *            |------ child ------|
+             * or
+             *     |--------------- me ---------------|
+             *                                  |------ child ------|
+             *
+             * n < 0 is this case:
+             *     |------ me ------|
+             *                    |-------- child --------|
+             *     |-- mScrollX --|
+             */
+            return 0;
+        }
+        if ((my+n) > child) {
+            /* this case:
+             *                    |------ me ------|
+             *     |------ child ------|
+             *     |-- mScrollX --|
+             */
+            return child-my;
+        }
+        return n;
+    }
+
+}
