diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index eeca95a..a841989 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -31,10 +31,13 @@
 import android.widget.Gallery;
 import android.widget.ImageButton;
 import android.widget.ImageView;
+import android.widget.LinearLayout;
 import android.widget.ListPopupWindow;
 import android.widget.RelativeLayout;
 import android.widget.TextView;
 
+import com.android.browser.view.Gallery.OnItemSelectedListener;
+
 import java.util.ArrayList;
 import java.util.List;
 
@@ -57,7 +60,7 @@
     ImageView mFavicon;
     ImageButton mCloseTab;
 
-    NavTabScroller mScroller;
+    NavTabGallery mScroller;
     float mTabAspect = 0.66f;
     int mTabWidth;
     int mTabHeight;
@@ -111,9 +114,9 @@
         if (newconfig.orientation != mOrientation) {
             int selIx = mScroller.getSelectionIndex();
             removeAllViews();
+            mOrientation = newconfig.orientation;
             init();
             mScroller.setSelection(selIx);
-            mOrientation = newconfig.orientation;
             mAdapter.notifyDataSetChanged();
         }
     }
@@ -128,10 +131,11 @@
         mNewTab.setOnClickListener(this);
         mNewIncognito.setOnClickListener(this);
         mMore.setOnClickListener(this);
-        mScroller = (NavTabScroller) findViewById(R.id.scroller);
+        mScroller = (NavTabGallery) findViewById(R.id.scroller);
         mAdapter = new TabAdapter(mContext, mUiController.getTabControl());
         mScroller.setAdapter(mAdapter);
-
+        mScroller.setOrientation(mOrientation == Configuration.ORIENTATION_LANDSCAPE
+                ? LinearLayout.HORIZONTAL : LinearLayout.VERTICAL);
         // update state for active tab
         mScroller.setSelection(mUiController.getTabControl().getTabPosition(mUi.getActiveTab()));
     }
@@ -261,19 +265,13 @@
             tabview.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    if (tabview.isRefresh(v)) {
-                        mUi.hideNavScreen(true);
-                        web.reload();
-                    } else if (tabview.isClose(v)) {
+                    if (tabview.isClose(v)) {
                         onCloseTab((Tab) (mScroller.getSelectedItem()));
                     } else if (tabview.isTitle(v)) {
                         mUi.getTitleBar().setSkipTitleBarAnimations(true);
                         close(false);
                         mUi.editUrl(false);
                         mUi.getTitleBar().setSkipTitleBarAnimations(false);
-                    } else if (tabview.isForward(v)) {
-                        mUi.hideNavScreen(true);
-                        web.goForward();
                     } else if (tabview.isWebView(v)) {
                         mScroller.setSelection(position);
                         close();
diff --git a/src/com/android/browser/NavTabGallery.java b/src/com/android/browser/NavTabGallery.java
new file mode 100644
index 0000000..3014eaf
--- /dev/null
+++ b/src/com/android/browser/NavTabGallery.java
@@ -0,0 +1,58 @@
+/*
+ * 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.content.Context;
+import android.util.AttributeSet;
+import android.view.View;
+
+import com.android.browser.view.Gallery;
+
+/**
+ * custom view for displaying tabs in the nav screen
+ */
+public class NavTabGallery extends Gallery {
+
+    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);
+    }
+
+    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();
+    }
+
+}
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
deleted file mode 100644
index 312e2b8..0000000
--- a/src/com/android/browser/NavTabScroller.java
+++ /dev/null
@@ -1,377 +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.content.Context;
-import android.content.res.Configuration;
-import android.database.DataSetObserver;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.BaseAdapter;
-import android.widget.FrameLayout;
-import android.widget.LinearLayout;
-
-import com.android.browser.view.HorizontalScrollView;
-import com.android.browser.view.ScrollView;
-
-/**
- * custom view for displaying tabs in the nav screen
- */
-public class NavTabScroller extends FrameLayout {
-
-    private LinearLayout mContentView;
-    private BaseAdapter mAdapter;
-    private SelectableSroller mScroller;
-    private int mOrientation;
-
-    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) {
-        mOrientation = ctx.getResources().getConfiguration().orientation;
-        mScroller = (mOrientation == Configuration.ORIENTATION_LANDSCAPE) ?
-                new HorizontalScroller(ctx) : new VerticalScroller(ctx);
-        mContentView = mScroller.getContentView();
-        View sview = (View) mScroller;
-        sview.setLayoutParams(new FrameLayout.LayoutParams(LayoutParams.MATCH_PARENT,
-                LayoutParams.MATCH_PARENT));
-        addView(sview);
-    }
-
-    @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 (mOrientation == Configuration.ORIENTATION_PORTRAIT) {
-                int pad = (getMeasuredHeight() - v.getMeasuredHeight()) / 2;
-                mContentView.setPadding(0, pad, 0, pad);
-            } else {
-                int pad = (getMeasuredWidth() - v.getMeasuredWidth()) / 2;
-                mContentView.setPadding(pad, 0, pad, 0);
-            }
-        }
-    }
-
-    protected void setAdapter(BaseAdapter adapter) {
-        mAdapter = adapter;
-        mAdapter.registerDataSetObserver(new DataSetObserver() {
-
-            @Override
-            public void onChanged() {
-                super.onChanged();
-                populateList();
-            }
-
-            @Override
-            public void onInvalidated() {
-                super.onInvalidated();
-            }
-        });
-        populateList();
-    }
-
-    protected void setSelection(int ix) {
-        mScroller.setSelection(ix);
-    }
-
-    protected int getSelectionIndex() {
-        return mScroller.getSelection();
-    }
-
-    protected Tab getSelectedItem() {
-        return (Tab) mAdapter.getItem(mScroller.getSelection());
-    }
-
-    protected ViewGroup getContentView() {
-        return mContentView;
-    }
-
-    private void populateList() {
-        mContentView.removeAllViewsInLayout();
-        for (int i = 0; i < mAdapter.getCount(); i++) {
-            NavTabView v = (NavTabView) mAdapter.getView(i, null, mContentView);
-            mContentView.addView(v);
-        }
-    }
-
-    View getSelectedTab() {
-        int selected = mScroller.getSelection();
-        if ((selected >= 0) && (selected < mContentView.getChildCount())) {
-            return mContentView.getChildAt(selected);
-        } else {
-            return null;
-        }
-    }
-
-    static interface SelectableSroller {
-        void setSelection(int index);
-        int getSelection();
-        LinearLayout getContentView();
-
-    }
-
-    static class VerticalScroller extends ScrollView implements SelectableSroller  {
-
-        private LinearLayout mContentView;
-        private int mSelected;
-        private boolean mSnapScroll;
-
-        public VerticalScroller(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
-            init(context);
-        }
-
-        public VerticalScroller(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            init(context);
-        }
-
-        public VerticalScroller(Context context) {
-            super(context);
-            init(context);
-        }
-
-        private void init(Context ctx) {
-            setHorizontalScrollBarEnabled(false);
-            mContentView = new LinearLayout(ctx);
-            mContentView.setOrientation(LinearLayout.VERTICAL);
-            setVerticalScrollBarEnabled(false);
-            setSmoothScrollingEnabled(true);
-            mContentView.setLayoutParams(
-                    new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
-            addView(mContentView);
-
-        }
-
-        public LinearLayout getContentView() {
-            return mContentView;
-        }
-
-        public void setSelection(int ix) {
-            mSelected = ix;
-        }
-
-        public int getSelection() {
-            return mSelected;
-        }
-
-        protected void onScrollChanged(int sl, int st, int ol, int ot) {
-            int midy = getScrollY() + getHeight() / 2;
-            int sel = -1;
-            for (int i = 0; i < mContentView.getChildCount(); i++) {
-                NavTabView child = (NavTabView) mContentView.getChildAt(i);
-                int top = child.getTop();
-                int bottom = child.getBottom();
-                if (top <= midy && bottom >= midy) {
-                    sel = i;
-                    break;
-                }
-            }
-            if (sel != -1) {
-                if (sel != mSelected) {
-                    setSelection(sel);
-                }
-            }
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent evt) {
-            // save drag state before super call
-            boolean dragged = mIsBeingDragged;
-            boolean result = super.onTouchEvent(evt);
-            if (MotionEvent.ACTION_UP == evt.getActionMasked()) {
-                if (mScroller.isFinished() && dragged) {
-                    snapToSelected();
-                }
-            } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
-                NavTabView ntv = (NavTabView) getSelectedView();
-                if (mIsBeingDragged && ntv.isHighlighted()) {
-                    ntv.setHighlighted(false);
-                }
-            }
-            return result;
-        }
-
-        @Override
-        public void computeScroll() {
-            super.computeScroll();
-            if (mScroller.isFinished() && !mIsBeingDragged) {
-                if (!mSnapScroll) {
-                    snapToSelected();
-                } else {
-                    // reset snap scrolling flag
-                    mSnapScroll = false;
-                    NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(true);
-                }
-            }
-        }
-
-        private void snapToSelected() {
-            View v = mContentView.getChildAt(mSelected);
-            int top = (v.getTop() + v.getBottom()) / 2;
-            top -= getHeight() / 2;
-            if (top != getScrollY()) {
-                // snap to selected
-                mSnapScroll = true;
-                smoothScrollTo(0, top);
-            } else {
-                NavTabView ntv = (NavTabView) getSelectedView();
-                ntv.setHighlighted(true);
-            }
-        }
-
-        protected View getSelectedView() {
-            return mContentView.getChildAt(mSelected);
-        }
-
-    }
-
-    static class HorizontalScroller extends HorizontalScrollView implements SelectableSroller  {
-
-        private LinearLayout mContentView;
-        private int mSelected;
-        private boolean mSnapScroll;
-
-        public HorizontalScroller(Context context, AttributeSet attrs, int defStyle) {
-            super(context, attrs, defStyle);
-            init(context);
-        }
-
-        public HorizontalScroller(Context context, AttributeSet attrs) {
-            super(context, attrs);
-            init(context);
-        }
-
-        public HorizontalScroller(Context context) {
-            super(context);
-            init(context);
-        }
-
-        private void init(Context ctx) {
-            setHorizontalScrollBarEnabled(false);
-            mContentView = new LinearLayout(ctx);
-            mContentView.setOrientation(LinearLayout.HORIZONTAL);
-            setVerticalScrollBarEnabled(false);
-            setSmoothScrollingEnabled(true);
-            mContentView.setLayoutParams(
-                    new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
-            addView(mContentView);
-        }
-
-        public LinearLayout getContentView() {
-            return mContentView;
-        }
-
-        public void setSelection(int ix) {
-            mSelected = ix;
-        }
-
-        public int getSelection() {
-            return mSelected;
-        }
-
-        protected void onScrollChanged(int sl, int st, int ol, int ot) {
-            int midx = getScrollX() + getWidth() / 2;
-            int sel = -1;
-            for (int i = 0; i < mContentView.getChildCount(); i++) {
-                View child = mContentView.getChildAt(i);
-                if (child.getLeft() <= midx && child.getRight() >= midx) {
-                    sel = i;
-                    break;
-                }
-            }
-            if (sel != -1) {
-                if (sel != mSelected) {
-                    setSelection(sel);
-                }
-            }
-        }
-
-        @Override
-        public boolean onTouchEvent(MotionEvent evt) {
-            // save drag state before super call
-            boolean dragged = mIsBeingDragged;
-            boolean result = super.onTouchEvent(evt);
-            if (MotionEvent.ACTION_UP == evt.getActionMasked()) {
-                if (mScroller.isFinished() && dragged) {
-                    snapToSelected();
-                }
-            } else if (MotionEvent.ACTION_MOVE == evt.getActionMasked()) {
-                NavTabView ntv = (NavTabView) getSelectedView();
-                if (mIsBeingDragged && ntv.isHighlighted()) {
-                    ntv.setHighlighted(false);
-                }
-            }
-            return result;
-        }
-
-        @Override
-        public void computeScroll() {
-            super.computeScroll();
-            if (mScroller.isFinished() && !mIsBeingDragged) {
-                if (!mSnapScroll) {
-                    snapToSelected();
-                } else {
-                    // reset snap scrolling flag
-                    mSnapScroll = false;
-                    NavTabView ntv = (NavTabView) getSelectedView();
-                    ntv.setHighlighted(true);
-                }
-            }
-        }
-
-        private void snapToSelected() {
-            View v = mContentView.getChildAt(mSelected);
-            int left = (v.getLeft() + v.getRight()) / 2;
-            left -= getWidth() / 2;
-            if (left != getScrollX()) {
-                // snap to selected
-                mSnapScroll = true;
-                smoothScrollTo(left, 0);
-            } else {
-                NavTabView ntv = (NavTabView) getSelectedView();
-                ntv.setHighlighted(true);
-            }
-        }
-
-        protected View getSelectedView() {
-            return mContentView.getChildAt(mSelected);
-        }
-
-    }
-
-}
diff --git a/src/com/android/browser/NavTabView.java b/src/com/android/browser/NavTabView.java
index daa5013..7b547b8 100644
--- a/src/com/android/browser/NavTabView.java
+++ b/src/com/android/browser/NavTabView.java
@@ -36,19 +36,12 @@
     private Tab mTab;
     private BrowserWebView mWebView;
     private WebProxyView mProxy;
-    private ImageButton mForward;
-    private ImageButton mRefresh;
-    private ImageView mFavicon;
-    private ImageButton mClose;
+    private ImageView mClose;
     private FrameLayout mContainer;
     private TextView mTitle;
     private View mTitleBar;
     private OnClickListener mClickListener;
     private boolean mHighlighted;
-    private Drawable mTitleBg;
-    private Drawable mUrlBg;
-    private float mMediumTextSize;
-    private float mSmallTextSize;
 
     public NavTabView(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -66,26 +59,11 @@
     }
 
     private void init() {
-        final Resources res = mContext.getResources();
-        mMediumTextSize = res.getDimension(R.dimen.nav_tab_text_normal);
-        mSmallTextSize = res.getDimension(R.dimen.nav_tab_text_small);
-        LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view,
-                    this);
+        LayoutInflater.from(mContext).inflate(R.layout.nav_tab_view, this);
         mContainer = (FrameLayout) findViewById(R.id.tab_view);
-        mForward = (ImageButton) findViewById(R.id.forward);
-        mClose = (ImageButton) findViewById(R.id.closetab);
-        mRefresh = (ImageButton) findViewById(R.id.refresh);
+        mClose = (ImageView) findViewById(R.id.closetab);
         mTitle = (TextView) findViewById(R.id.title);
-        mFavicon = (ImageView) findViewById(R.id.favicon);
         mTitleBar = findViewById(R.id.titlebar);
-        mTitleBg = res.getDrawable(R.drawable.bg_urlbar);
-        mUrlBg = res.getDrawable(
-                com.android.internal.R.drawable.edit_text_holo_dark);
-        setState(false);
-    }
-
-    protected boolean isRefresh(View v) {
-        return v == mRefresh;
     }
 
     protected boolean isClose(View v) {
@@ -96,10 +74,6 @@
         return v == mTitleBar;
     }
 
-    protected boolean isForward(View v) {
-        return v == mForward;
-    }
-
     protected boolean isWebView(View v) {
         return v == mProxy;
     }
@@ -107,29 +81,6 @@
     protected void setHighlighted(boolean highlighted) {
         if (highlighted == mHighlighted) return;
         mHighlighted = highlighted;
-        setState(highlighted);
-    }
-
-    private void setState(boolean highlighted) {
-        if (highlighted) {
-            setAlpha(1.0f);
-            mFavicon.setVisibility(View.VISIBLE);
-            setupButtons();
-            mTitleBar.setBackgroundDrawable(mTitleBg);
-            mClose.setVisibility(View.VISIBLE);
-            mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mMediumTextSize);
-            mTitle.setBackgroundDrawable(mUrlBg);
-        } else {
-            setAlpha(0.8f);
-            mForward.setVisibility(View.GONE);
-            mRefresh.setVisibility(View.INVISIBLE);
-            mFavicon.setVisibility(View.INVISIBLE);
-            mClose.setVisibility(View.GONE);
-            mTitleBar.setBackgroundDrawable(null);
-            mTitle.setTextSize(TypedValue.COMPLEX_UNIT_PX, mSmallTextSize);
-            mTitle.setBackgroundDrawable(null);
-        }
-        setTitle();
     }
 
     private void setTitle() {
@@ -138,7 +89,9 @@
             mTitle.setText(mTab.getUrl());
         } else {
             String txt = mTab.getTitle();
-            if (txt == null) txt = mTab.getUrl();
+            if (txt == null) {
+                txt = mTab.getUrl();
+            }
             mTitle.setText(txt);
         }
     }
@@ -149,7 +102,6 @@
 
     protected void setWebView(PhoneUi ui, Tab tab) {
         mTab = tab;
-        mFavicon.setImageDrawable(ui.getFaviconDrawable(tab.getFavicon()));
         setTitle();
         BrowserWebView web = (BrowserWebView) tab.getWebView();
         if (web != null) {
@@ -158,18 +110,6 @@
             mProxy = new WebProxyView(mContext, mWebView);
             mContainer.addView(mProxy, 0);
         }
-        setupButtons();
-    }
-
-    void setupButtons() {
-        if (mTab.isSnapshot()) {
-            mForward.setVisibility(View.GONE);
-            mRefresh.setVisibility(View.GONE);
-        } else if (mWebView != null) {
-            mForward.setVisibility(mWebView.canGoForward()
-                    ? View.VISIBLE : View.GONE);
-            mRefresh.setVisibility(View.VISIBLE);
-        }
     }
 
     protected void hideTitle() {
@@ -180,8 +120,6 @@
     public void setOnClickListener(OnClickListener listener) {
         mClickListener = listener;
         mTitleBar.setOnClickListener(mClickListener);
-        mRefresh.setOnClickListener(mClickListener);
-        mForward.setOnClickListener(mClickListener);
         mClose.setOnClickListener(mClickListener);
         if (mProxy != null) {
             mProxy.setOnClickListener(mClickListener);
@@ -195,6 +133,13 @@
         }
     }
 
+    @Override
+    public void onAttachedToWindow() {
+        if (mWebView != null) {
+            mWebView.invalidate();
+        }
+    }
+
     private static void removeFromParent(View v) {
         if (v.getParent() != null) {
             ((ViewGroup) v.getParent()).removeView(v);
@@ -214,7 +159,11 @@
         }
 
         public void onDraw(Canvas c) {
-            c.translate(-mWeb.getScrollX(), -mWeb.getScrollY());
+            float scale = 0.7f;
+            int sx = mWeb.getScrollX();
+            int sy = mWeb.getScrollY();
+            c.scale(scale, scale);
+            c.translate(-sx, -sy);
             mWeb.onDraw(c);
         }
 
diff --git a/src/com/android/browser/view/Gallery.java b/src/com/android/browser/view/Gallery.java
new file mode 100644
index 0000000..fa3f97a
--- /dev/null
+++ b/src/com/android/browser/view/Gallery.java
@@ -0,0 +1,1396 @@
+/*
+ * 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.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.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;
+
+    private boolean mHorizontal;
+    private 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;
+
+    private int mDownTouchPosition;
+    private View mDownTouchView;
+    private FlingRunnable mFlingRunnable = new FlingRunnable();
+
+    private OnItemSelectedListener mOnItemSelectedListener;
+    private SelectionNotifier mSelectionNotifier;
+
+    /**
+     * 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;
+
+    private int mActivePointerId = INVALID_POINTER;
+
+    private int mTouchSlop;
+
+    private float mLastMotionCoord;
+
+    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);
+    }
+
+    /**
+     * 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);
+
+    }
+
+    /**
+     * 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();
+    }
+
+    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();
+    }
+
+    void handleDataChanged() {
+        if (mAdapter != null) {
+            resetList();
+            mItemCount = mAdapter.getCount();
+            // checkFocus();
+            int position = mItemCount > 0 ? 0 : INVALID_POSITION;
+            if (mSelectedPosition >= 0) {
+                position = Math.min(mItemCount - 1, mSelectedPosition);
+            }
+            setSelectedPositionInt(position);
+            if (mItemCount == 0) {
+                // Nothing selected
+                checkSelectionChanged();
+            }
+        } else {
+            // checkFocus();
+            mOldSelectedPosition = INVALID_POSITION;
+            setSelectedPositionInt(INVALID_POSITION);
+            resetList();
+            // Nothing selected
+            checkSelectionChanged();
+        }
+    }
+
+    /**
+     * Clear out all children from the list
+     */
+    void resetList() {
+        mDataChanged = false;
+        removeAllViewsInLayout();
+        invalidate();
+    }
+
+    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) {
+        t.clear();
+        t.setAlpha(child == mSelectedChild ? 1.0f : mUnselectedAlpha);
+        return true;
+    }
+
+    @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.
+     */
+    void trackMotionScroll(int deltaX) {
+        if (getChildCount() == 0) {
+            return;
+        }
+        boolean toLeft = deltaX < 0;
+        int limitedDeltaX = 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();
+        }
+        // Clear unused views
+        mRecycler.clear();
+        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();
+        mRecycler.clear();
+        invalidate();
+        checkSelectionChanged();
+        mDataChanged = false;
+        updateSelectedItemMetadata();
+    }
+
+    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 - mBottom - 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 posiitoning 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
+     */
+    private 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;
+        }
+        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;
+                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();
+            mGestureDetector.onTouchEvent(ev);
+            break;
+        }
+        case MotionEvent.ACTION_CANCEL:
+        case MotionEvent.ACTION_UP:
+            /* Release the drag */
+            mIsBeingDragged = false;
+            mActivePointerId = INVALID_POINTER;
+            break;
+        case MotionEvent.ACTION_POINTER_DOWN: {
+            final int index = ev.getActionIndex();
+            mLastMotionCoord = mHorizontal ? ev.getX(index) : ev.getY(index);
+            mActivePointerId = ev.getPointerId(index);
+            break;
+        }
+        case MotionEvent.ACTION_POINTER_UP:
+            mLastMotionCoord = ev.getX(ev.findPointerIndex(mActivePointerId));
+            break;
+        }
+
+        return mIsBeingDragged;
+    }
+
+    @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();
+        } 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;
+        }
+        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 (!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;
+    }
+
+    public boolean onDown(MotionEvent e) {
+        mFlingRunnable.stop(false);
+        mDownTouchPosition = pointToPosition((int) e.getX(), (int) e.getY());
+        if (mDownTouchPosition >= 0) {
+            mDownTouchView = getChildAt(mDownTouchPosition - mFirstPosition);
+            mDownTouchView.setPressed(true);
+        }
+        // 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.
+     */
+    void onUp() {
+        if (mFlingRunnable.mScroller.isFinished()) {
+            scrollIntoSlots();
+        }
+        dispatchUnpress();
+    }
+
+    /**
+     * Called when a touch event's action is MotionEvent.ACTION_CANCEL.
+     */
+    void onCancel() {
+        onUp();
+    }
+
+    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) {
+        if (mSelectedChild != null) {
+            mSelectedChild.setPressed(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) {
+    }
+
+    boolean movePrevious() {
+        if (mItemCount > 0 && mSelectedPosition > 0) {
+            scrollToChild(mSelectedPosition - mFirstPosition - 1);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    boolean moveNext() {
+        if (mItemCount > 0 && mSelectedPosition < mItemCount - 1) {
+            scrollToChild(mSelectedPosition - mFirstPosition + 1);
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean scrollToChild(int childPosition) {
+        View child = getChildAt(childPosition);
+        if (child != null) {
+            int distance = getCenterOfGallery() - getCenterOfView(child);
+            mFlingRunnable.startUsingDistance(distance);
+            return true;
+        }
+        return false;
+    }
+
+    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 int getChildDrawingOrder(int childCount, int i) {
+        int selectedIndex = mSelectedPosition - mFirstPosition;
+        // Just to be safe
+        if (selectedIndex < 0)
+            return i;
+        if (i == childCount - 1) {
+            // Draw the selected child last
+            return selectedIndex;
+        } else if (i >= selectedIndex) {
+            // Move the children to the right of the selected child earlier one
+            return i + 1;
+        } else {
+            // Keep the children to the left of the selected child the same
+            return i;
+        }
+    }
+
+    @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) {
+            if (distance == 0)
+                return;
+            startCommon();
+            mLastFlingX = 0;
+            mScroller.startScroll(0, 0, -distance, 0, mAnimationDuration);
+            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/HorizontalScrollView.java b/src/com/android/browser/view/HorizontalScrollView.java
deleted file mode 100644
index 2da9058..0000000
--- a/src/com/android/browser/view/HorizontalScrollView.java
+++ /dev/null
@@ -1,1453 +0,0 @@
-/*
- * Copyright (C) 2009 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 com.android.internal.R;
-
-import android.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-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.animation.AnimationUtils;
-import android.widget.EdgeGlow;
-import android.widget.FrameLayout;
-import android.widget.OverScroller;
-
-import java.util.List;
-
-// copied from frameworks to allow for customizations
-public class HorizontalScrollView extends FrameLayout {
-
-    private static final int ANIMATED_SCROLL_GAP = 250;
-
-    private static final float MAX_SCROLL_FACTOR = 0.5f;
-
-
-    private long mLastScroll;
-
-    private final Rect mTempRect = new Rect();
-    protected OverScroller mScroller;
-    private EdgeGlow mEdgeGlowLeft;
-    private EdgeGlow mEdgeGlowRight;
-
-    /**
-     * Position of the last motion event.
-     */
-    private float mLastMotionX;
-
-    /**
-     * 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.
-     */
-    private 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;
-    private 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;
-
-    /**
-     * Sentinel value for no current active pointer.
-     * Used by {@link #mActivePointerId}.
-     */
-    private static final int INVALID_POINTER = -1;
-
-    public HorizontalScrollView(Context context) {
-        this(context, null);
-    }
-
-    public HorizontalScrollView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.horizontalScrollViewStyle);
-    }
-
-    public HorizontalScrollView(Context context, AttributeSet attrs, int defStyle) {
-        super(context, attrs, defStyle);
-        initScrollView();
-
-        TypedArray a = context.obtainStyledAttributes(attrs,
-                android.R.styleable.HorizontalScrollView, defStyle, 0);
-
-        setFillViewport(a.getBoolean(android.R.styleable.HorizontalScrollView_fillViewport, false));
-
-        a.recycle();
-    }
-
-    @Override
-    protected float getLeftFadingEdgeStrength() {
-        return 0.0f;
-    }
-
-    @Override
-    protected float getRightFadingEdgeStrength() {
-        return 0.0f;
-    }
-
-    /**
-     * @return The maximum amount this scroll view will scroll in response to
-     *   an arrow event.
-     */
-    public int getMaxScrollAmount() {
-        return (int) (MAX_SCROLL_FACTOR * (mRight - mLeft));
-    }
-
-
-    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();
-    }
-
-    @Override
-    public void addView(View child) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("HorizontalScrollView can host only one direct child");
-        }
-
-        super.addView(child);
-    }
-
-    @Override
-    public void addView(View child, int index) {
-        if (getChildCount() > 0) {
-            throw new IllegalStateException("HorizontalScrollView 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("HorizontalScrollView 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("HorizontalScrollView can host only one direct child");
-        }
-
-        super.addView(child, index, params);
-    }
-
-    /**
-     * @return Returns true this HorizontalScrollView can be scrolled
-     */
-    private boolean canScroll() {
-        View child = getChildAt(0);
-        if (child != null) {
-            int childWidth = child.getWidth();
-            return getWidth() < childWidth + mPaddingLeft + mPaddingRight ;
-        }
-        return false;
-    }
-
-    /**
-     * Indicates whether this HorizontalScrollView's content is stretched to
-     * fill the viewport.
-     *
-     * @return True if the content fills the viewport, false otherwise.
-     *
-     * @attr ref android.R.styleable#HorizontalScrollView_fillViewport
-     */
-    public boolean isFillViewport() {
-        return mFillViewport;
-    }
-
-    /**
-     * Indicates this HorizontalScrollView whether it should stretch its content width
-     * to fill the viewport or not.
-     *
-     * @param fillViewport True to stretch the content's width to the viewport's
-     *        boundaries, false otherwise.
-     *
-     * @attr ref android.R.styleable#HorizontalScrollView_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 widthMode = MeasureSpec.getMode(widthMeasureSpec);
-        if (widthMode == MeasureSpec.UNSPECIFIED) {
-            return;
-        }
-
-        if (getChildCount() > 0) {
-            final View child = getChildAt(0);
-            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);
-            }
-        }
-    }
-
-    @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()) {
-                View currentFocused = findFocus();
-                if (currentFocused == this) currentFocused = null;
-                View nextFocused = FocusFinder.getInstance().findNextFocus(this,
-                        currentFocused, View.FOCUS_RIGHT);
-                return nextFocused != null && nextFocused != this &&
-                        nextFocused.requestFocus(View.FOCUS_RIGHT);
-            }
-            return false;
-        }
-
-        boolean handled = false;
-        if (event.getAction() == KeyEvent.ACTION_DOWN) {
-            switch (event.getKeyCode()) {
-                case KeyEvent.KEYCODE_DPAD_LEFT:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_LEFT);
-                    } else {
-                        handled = fullScroll(View.FOCUS_LEFT);
-                    }
-                    break;
-                case KeyEvent.KEYCODE_DPAD_RIGHT:
-                    if (!event.isAltPressed()) {
-                        handled = arrowScroll(View.FOCUS_RIGHT);
-                    } else {
-                        handled = fullScroll(View.FOCUS_RIGHT);
-                    }
-                    break;
-                case KeyEvent.KEYCODE_SPACE:
-                    pageScroll(event.isShiftPressed() ? View.FOCUS_LEFT : View.FOCUS_RIGHT);
-                    break;
-            }
-        }
-
-        return handled;
-    }
-
-    private boolean inChild(int x, int y) {
-        if (getChildCount() > 0) {
-            final int scrollX = mScrollX;
-            final View child = getChildAt(0);
-            return !(y < child.getTop()
-                    || y >= child.getBottom()
-                    || x < child.getLeft() - scrollX
-                    || x >= child.getRight() - scrollX);
-        }
-        return false;
-    }
-
-    @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;
-        }
-
-        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. mLastMotionX is set to the x 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 x = ev.getX(pointerIndex);
-                final int xDiff = (int) Math.abs(x - mLastMotionX);
-                if (xDiff > mTouchSlop) {
-                    mIsBeingDragged = true;
-                    mLastMotionX = x;
-                    if (mParent != null) mParent.requestDisallowInterceptTouchEvent(true);
-                }
-                break;
-            }
-
-            case MotionEvent.ACTION_DOWN: {
-                final float x = ev.getX();
-                if (!inChild((int) x, (int) ev.getY())) {
-                    mIsBeingDragged = false;
-                    break;
-                }
-
-                /*
-                 * Remember location of down touch.
-                 * ACTION_DOWN always refers to pointer index 0.
-                 */
-                mLastMotionX = x;
-                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 = !mScroller.isFinished();
-                break;
-            }
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                /* Release the drag */
-                mIsBeingDragged = false;
-                mActivePointerId = INVALID_POINTER;
-                if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
-                    invalidate();
-                }
-                break;
-            case MotionEvent.ACTION_POINTER_DOWN: {
-                final int index = ev.getActionIndex();
-                mLastMotionX = ev.getX(index);
-                mActivePointerId = ev.getPointerId(index);
-                break;
-            }
-            case MotionEvent.ACTION_POINTER_UP:
-                onSecondaryPointerUp(ev);
-                mLastMotionX = ev.getX(ev.findPointerIndex(mActivePointerId));
-                break;
-        }
-
-        /*
-        * The only time we want to intercept motion events is if we are in the
-        * drag mode.
-        */
-        return mIsBeingDragged;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-
-        if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
-            // Don't handle edge touches immediately -- they may actually belong to one of our
-            // descendants.
-            return false;
-        }
-
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        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();
-                }
-
-                // Remember where the motion event started
-                mLastMotionX = ev.getX();
-                mActivePointerId = ev.getPointerId(0);
-                break;
-            }
-            case MotionEvent.ACTION_MOVE:
-                if (mIsBeingDragged) {
-                    // Scroll to follow the motion event
-                    final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
-                    final float x = ev.getX(activePointerIndex);
-                    final int deltaX = (int) (mLastMotionX - x);
-                    mLastMotionX = x;
-
-                    final int oldX = mScrollX;
-                    final int oldY = mScrollY;
-                    final int range = getScrollRange();
-                    if (overScrollBy(deltaX, 0, mScrollX, 0, range, 0,
-                            mOverscrollDistance, 0, 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 pulledToX = oldX + deltaX;
-                        if (pulledToX < 0) {
-                            mEdgeGlowLeft.onPull((float) deltaX / getWidth());
-                            if (!mEdgeGlowRight.isFinished()) {
-                                mEdgeGlowRight.onRelease();
-                            }
-                        } else if (pulledToX > range) {
-                            mEdgeGlowRight.onPull((float) deltaX / getWidth());
-                            if (!mEdgeGlowLeft.isFinished()) {
-                                mEdgeGlowLeft.onRelease();
-                            }
-                        }
-                        if (mEdgeGlowLeft != null
-                                && (!mEdgeGlowLeft.isFinished() || !mEdgeGlowRight.isFinished())) {
-                            invalidate();
-                        }
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-                if (mIsBeingDragged) {
-                    final VelocityTracker velocityTracker = mVelocityTracker;
-                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                    int initialVelocity = (int) velocityTracker.getXVelocity(mActivePointerId);
-
-                    if (getChildCount() > 0) {
-                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                            fling(-initialVelocity);
-                        } else {
-                            final int right = getScrollRange();
-                            if (mScroller.springBack(mScrollX, mScrollY, 0, right, 0, 0)) {
-                                invalidate();
-                            }
-                        }
-                    }
-
-                    mActivePointerId = INVALID_POINTER;
-                    mIsBeingDragged = false;
-
-                    if (mVelocityTracker != null) {
-                        mVelocityTracker.recycle();
-                        mVelocityTracker = null;
-                    }
-                    if (mEdgeGlowLeft != null) {
-                        mEdgeGlowLeft.onRelease();
-                        mEdgeGlowRight.onRelease();
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                if (mIsBeingDragged && getChildCount() > 0) {
-                    if (mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0)) {
-                        invalidate();
-                    }
-                    mActivePointerId = INVALID_POINTER;
-                    mIsBeingDragged = false;
-                    if (mVelocityTracker != null) {
-                        mVelocityTracker.recycle();
-                        mVelocityTracker = null;
-                    }
-                    if (mEdgeGlowLeft != null) {
-                        mEdgeGlowLeft.onRelease();
-                        mEdgeGlowRight.onRelease();
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_POINTER_UP:
-                onSecondaryPointerUp(ev);
-                break;
-        }
-        return true;
-    }
-
-    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;
-            mLastMotionX = ev.getX(newPointerIndex);
-            mActivePointerId = ev.getPointerId(newPointerIndex);
-            if (mVelocityTracker != null) {
-                mVelocityTracker.clear();
-            }
-        }
-    }
-
-    @Override
-    public boolean onGenericMotionEvent(MotionEvent event) {
-        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_SCROLL: {
-                    if (!mIsBeingDragged) {
-                        final float hscroll;
-                        if ((event.getMetaState() & KeyEvent.META_SHIFT_ON) != 0) {
-                            hscroll = -event.getAxisValue(MotionEvent.AXIS_VSCROLL);
-                        } else {
-                            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;
-                            }
-                        }
-                    }
-                }
-            }
-        }
-        return super.onGenericMotionEvent(event);
-    }
-
-    @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 (clampedX) {
-                mScroller.springBack(mScrollX, mScrollY, 0, getScrollRange(), 0, 0);
-            }
-        } else {
-            super.scrollTo(scrollX, scrollY);
-        }
-        awakenScrollBars();
-    }
-
-    private int getScrollRange() {
-        int scrollRange = 0;
-        if (getChildCount() > 0) {
-            View child = getChildAt(0);
-            scrollRange = Math.max(0,
-                    child.getWidth() - (getWidth() - mPaddingLeft - mPaddingRight));
-        }
-        return scrollRange;
-    }
-
-    /**
-     * <p>
-     * Finds the next focusable component that fits in this View's bounds
-     * (excluding fading edges) pretending that this View's left is located at
-     * the parameter left.
-     * </p>
-     *
-     * @param leftFocus          look for a candidate is the one at the left of the bounds
-     *                           if leftFocus is true, or at the right of the bounds if leftFocus
-     *                           is false
-     * @param left               the left 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 leftFocus,
-            final int left, 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 = getHorizontalFadingEdgeLength() / 2;
-        final int leftWithoutFadingEdge = left + fadingEdgeLength;
-        final int rightWithoutFadingEdge = left + getWidth() - fadingEdgeLength;
-
-        if ((preferredFocusable != null)
-                && (preferredFocusable.getLeft() < rightWithoutFadingEdge)
-                && (preferredFocusable.getRight() > leftWithoutFadingEdge)) {
-            return preferredFocusable;
-        }
-
-        return findFocusableViewInBounds(leftFocus, leftWithoutFadingEdge,
-                rightWithoutFadingEdge);
-    }
-
-    /**
-     * <p>
-     * Finds the next focusable component that fits in the specified bounds.
-     * </p>
-     *
-     * @param leftFocus look for a candidate is the one at the left of the bounds
-     *                  if leftFocus is true, or at the right of the bounds if
-     *                  leftFocus is false
-     * @param left      the left offset of the bounds in which a focusable must be
-     *                  found
-     * @param right     the right 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 leftFocus, int left, int right) {
-
-        List<View> focusables = getFocusables(View.FOCUS_FORWARD);
-        View focusCandidate = null;
-
-        /*
-         * A fully contained focusable is one where its left is below the bound's
-         * left, and its right is above the bound's right. 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 viewLeft = view.getLeft();
-            int viewRight = view.getRight();
-
-            if (left < viewRight && viewLeft < right) {
-                /*
-                 * the focusable is in the target area, it is a candidate for
-                 * focusing
-                 */
-
-                final boolean viewIsFullyContained = (left < viewLeft) &&
-                        (viewRight < right);
-
-                if (focusCandidate == null) {
-                    /* No candidate, take this one */
-                    focusCandidate = view;
-                    foundFullyContainedFocusable = viewIsFullyContained;
-                } else {
-                    final boolean viewIsCloserToBoundary =
-                            (leftFocus && viewLeft < focusCandidate.getLeft()) ||
-                                    (!leftFocus && viewRight > focusCandidate.getRight());
-
-                    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;
-    }
-
-    /**
-     * <p>Handles scrolling in response to a "page up/down" shortcut press. This
-     * method will scroll the view by one page left or right and give the focus
-     * to the leftmost/rightmost 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_LEFT}
-     *                  to go one page left or {@link android.view.View#FOCUS_RIGHT}
-     *                  to go one page right
-     * @return true if the key event is consumed by this method, false otherwise
-     */
-    public boolean pageScroll(int direction) {
-        boolean right = direction == View.FOCUS_RIGHT;
-        int width = getWidth();
-
-        if (right) {
-            mTempRect.left = getScrollX() + width;
-            int count = getChildCount();
-            if (count > 0) {
-                View view = getChildAt(0);
-                if (mTempRect.left + width > view.getRight()) {
-                    mTempRect.left = view.getRight() - width;
-                }
-            }
-        } else {
-            mTempRect.left = getScrollX() - width;
-            if (mTempRect.left < 0) {
-                mTempRect.left = 0;
-            }
-        }
-        mTempRect.right = mTempRect.left + width;
-
-        return scrollAndFocus(direction, mTempRect.left, mTempRect.right);
-    }
-
-    /**
-     * <p>Handles scrolling in response to a "home/end" shortcut press. This
-     * method will scroll the view to the left or right and give the focus
-     * to the leftmost/rightmost 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_LEFT}
-     *                  to go the left of the view or {@link android.view.View#FOCUS_RIGHT}
-     *                  to go the right
-     * @return true if the key event is consumed by this method, false otherwise
-     */
-    public boolean fullScroll(int direction) {
-        boolean right = direction == View.FOCUS_RIGHT;
-        int width = getWidth();
-
-        mTempRect.left = 0;
-        mTempRect.right = width;
-
-        if (right) {
-            int count = getChildCount();
-            if (count > 0) {
-                View view = getChildAt(0);
-                mTempRect.right = view.getRight();
-                mTempRect.left = mTempRect.right - width;
-            }
-        }
-
-        return scrollAndFocus(direction, mTempRect.left, mTempRect.right);
-    }
-
-    /**
-     * <p>Scrolls the view to make the area defined by <code>left</code> and
-     * <code>right</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_LEFT}
-     *                  to go left {@link android.view.View#FOCUS_RIGHT} to right
-     * @param left     the left offset of the new area to be made visible
-     * @param right    the right 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 left, int right) {
-        boolean handled = true;
-
-        int width = getWidth();
-        int containerLeft = getScrollX();
-        int containerRight = containerLeft + width;
-        boolean goLeft = direction == View.FOCUS_LEFT;
-
-        View newFocused = findFocusableViewInBounds(goLeft, left, right);
-        if (newFocused == null) {
-            newFocused = this;
-        }
-
-        if (left >= containerLeft && right <= containerRight) {
-            handled = false;
-        } else {
-            int delta = goLeft ? (left - containerLeft) : (right - containerRight);
-            doScrollX(delta);
-        }
-
-        if (newFocused != findFocus()) newFocused.requestFocus(direction);
-
-        return handled;
-    }
-
-    /**
-     * Handle scrolling in response to a left or right 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)) {
-            nextFocused.getDrawingRect(mTempRect);
-            offsetDescendantRectToMyCoords(nextFocused, mTempRect);
-            int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-            doScrollX(scrollDelta);
-            nextFocused.requestFocus(direction);
-        } else {
-            // no new focus
-            int scrollDelta = maxJump;
-
-            if (direction == View.FOCUS_LEFT && getScrollX() < scrollDelta) {
-                scrollDelta = getScrollX();
-            } else if (direction == View.FOCUS_RIGHT && getChildCount() > 0) {
-
-                int daRight = getChildAt(0).getRight();
-
-                int screenRight = getScrollX() + getWidth();
-
-                if (daRight - screenRight < maxJump) {
-                    scrollDelta = daRight - screenRight;
-                }
-            }
-            if (scrollDelta == 0) {
-                return false;
-            }
-            doScrollX(direction == View.FOCUS_RIGHT ? 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;
-    }
-
-    /**
-     * @return whether the descendant of this scroll view is scrolled off
-     *  screen.
-     */
-    private boolean isOffScreen(View descendant) {
-        return !isWithinDeltaOfScreen(descendant, 0);
-    }
-
-    /**
-     * @return whether the descendant of this scroll view is within delta
-     *  pixels of being on the screen.
-     */
-    private boolean isWithinDeltaOfScreen(View descendant, int delta) {
-        descendant.getDrawingRect(mTempRect);
-        offsetDescendantRectToMyCoords(descendant, mTempRect);
-
-        return (mTempRect.right + delta) >= getScrollX()
-                && (mTempRect.left - delta) <= (getScrollX() + getWidth());
-    }
-
-    /**
-     * Smooth scroll by a X delta
-     *
-     * @param delta the number of pixels to scroll by on the X axis
-     */
-    private void doScrollX(int delta) {
-        if (delta != 0) {
-            if (mSmoothScrollingEnabled) {
-                smoothScrollBy(delta, 0);
-            } 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) {
-            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);
-            invalidate();
-        } else {
-            if (!mScroller.isFinished()) {
-                mScroller.abortAnimation();
-            }
-            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 width of all of its
-     * children.</p>
-     */
-    @Override
-    protected int computeHorizontalScrollRange() {
-        final int count = getChildCount();
-        final int contentWidth = getWidth() - mPaddingLeft - mPaddingRight;
-        if (count == 0) {
-            return contentWidth;
-        }
-
-        int scrollRange = getChildAt(0).getRight();
-        final int scrollX = mScrollX;
-        final int overscrollRight = Math.max(0, scrollRange - contentWidth);
-        if (scrollX < 0) {
-            scrollRange -= scrollX;
-        } else if (scrollX > overscrollRight) {
-            scrollRange += scrollX - overscrollRight;
-        }
-
-        return scrollRange;
-    }
-
-    @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;
-
-        childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec, mPaddingTop
-                + mPaddingBottom, lp.height);
-
-        childWidthMeasureSpec = 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();
-
-        final int childHeightMeasureSpec = getChildMeasureSpec(parentHeightMeasureSpec,
-                mPaddingTop + mPaddingBottom + lp.topMargin + lp.bottomMargin
-                        + heightUsed, lp.height);
-        final int childWidthMeasureSpec = MeasureSpec.makeMeasureSpec(
-                lp.leftMargin + lp.rightMargin, 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) {
-                overScrollBy(x - oldX, y - oldY, oldX, oldY, getScrollRange(), 0,
-                        mOverflingDistance, 0, false);
-                onScrollChanged(mScrollX, mScrollY, oldX, oldY);
-
-                final int range = getScrollRange();
-                final int overscrollMode = getOverScrollMode();
-                if (overscrollMode == OVER_SCROLL_ALWAYS ||
-                        (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
-                    if (x < 0 && oldX >= 0) {
-                        mEdgeGlowLeft.onAbsorb((int) mScroller.getCurrVelocity());
-                    } else if (x > range && oldX <= range) {
-                        mEdgeGlowRight.onAbsorb((int) mScroller.getCurrVelocity());
-                    }
-                }
-            }
-            awakenScrollBars();
-
-            // Keep on drawing until the animation has finished.
-            postInvalidate();
-        }
-    }
-
-    /**
-     * 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);
-
-        int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-
-        if (scrollDelta != 0) {
-            scrollBy(scrollDelta, 0);
-        }
-    }
-
-    /**
-     * 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
-     */
-    protected boolean scrollToChildRect(Rect rect, boolean immediate) {
-        final int delta = computeScrollDeltaToGetChildRectOnScreen(rect);
-        final boolean scroll = delta != 0;
-        if (scroll) {
-            if (immediate) {
-                scrollBy(delta, 0);
-            } else {
-                smoothScrollBy(delta, 0);
-            }
-        }
-        return scroll;
-    }
-
-    /**
-     * Compute the amount to scroll in the X 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 (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 (direction == View.FOCUS_FORWARD) {
-            direction = View.FOCUS_RIGHT;
-        } else if (direction == View.FOCUS_BACKWARD) {
-            direction = View.FOCUS_LEFT;
-        }
-
-        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 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;
-
-        final int maxJump = mRight - mLeft;
-
-        if (isWithinDeltaOfScreen(currentFocused, maxJump)) {
-            currentFocused.getDrawingRect(mTempRect);
-            offsetDescendantRectToMyCoords(currentFocused, mTempRect);
-            int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-            doScrollX(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 velocityX The initial velocity in the X direction. Positive
-     *                  numbers mean that the finger/curor is moving down the screen,
-     *                  which means we want to scroll towards the left.
-     */
-    public void fling(int velocityX) {
-        if (getChildCount() > 0) {
-            int width = getWidth() - mPaddingRight - mPaddingLeft;
-            int right = getChildAt(0).getWidth();
-
-            mScroller.fling(mScrollX, mScrollY, velocityX, 0, 0,
-                    Math.max(0, right - width), 0, 0, width/2, 0);
-
-            final boolean movingRight = velocityX > 0;
-
-            View currentFocused = findFocus();
-            View newFocused = findFocusableViewInMyBounds(movingRight,
-                    mScroller.getFinalX(), currentFocused);
-
-            if (newFocused == null) {
-                newFocused = this;
-            }
-
-            if (newFocused != currentFocused) {
-                newFocused.requestFocus(movingRight ? View.FOCUS_RIGHT : View.FOCUS_LEFT);
-            }
-
-            invalidate();
-        }
-    }
-
-    /**
-     * {@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);
-            }
-        }
-    }
-
-    @Override
-    public void setOverScrollMode(int mode) {
-        if (mode != OVER_SCROLL_NEVER) {
-            if (mEdgeGlowLeft == null) {
-                Context context = getContext();
-                final Resources res = context.getResources();
-                final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
-                final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
-                mEdgeGlowLeft = new EdgeGlow(context, edge, glow);
-                mEdgeGlowRight = new EdgeGlow(context, edge, glow);
-            }
-        } else {
-            mEdgeGlowLeft = null;
-            mEdgeGlowRight = null;
-        }
-        super.setOverScrollMode(mode);
-    }
-
-    @SuppressWarnings({"SuspiciousNameCombination"})
-    @Override
-    public void draw(Canvas canvas) {
-        super.draw(canvas);
-        if (mEdgeGlowLeft != null) {
-            final int scrollX = mScrollX;
-            if (!mEdgeGlowLeft.isFinished()) {
-                final int restoreCount = canvas.save();
-                final int height = getHeight() - mPaddingTop - mPaddingBottom;
-
-                canvas.rotate(270);
-                canvas.translate(-height + mPaddingTop, Math.min(0, scrollX));
-                mEdgeGlowLeft.setSize(height, getWidth());
-                if (mEdgeGlowLeft.draw(canvas)) {
-                    invalidate();
-                }
-                canvas.restoreToCount(restoreCount);
-            }
-            if (!mEdgeGlowRight.isFinished()) {
-                final int restoreCount = canvas.save();
-                final int width = getWidth();
-                final int height = getHeight() - mPaddingTop - mPaddingBottom;
-
-                canvas.rotate(90);
-                canvas.translate(-mPaddingTop,
-                        -(Math.max(getScrollRange(), scrollX) + width));
-                mEdgeGlowRight.setSize(height, width);
-                if (mEdgeGlowRight.draw(canvas)) {
-                    invalidate();
-                }
-                canvas.restoreToCount(restoreCount);
-            }
-        }
-    }
-
-    private int clamp(int n, int my, int child) {
-        if (my >= child || n < 0) {
-            return 0;
-        }
-        if ((my + n) > child) {
-            return child - my;
-        }
-        return n;
-    }
-}
diff --git a/src/com/android/browser/view/ScrollView.java b/src/com/android/browser/view/ScrollView.java
deleted file mode 100644
index ab09a8c..0000000
--- a/src/com/android/browser/view/ScrollView.java
+++ /dev/null
@@ -1,1538 +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.content.Context;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.graphics.Canvas;
-import android.graphics.Rect;
-import android.graphics.drawable.Drawable;
-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.animation.AnimationUtils;
-import android.widget.EdgeGlow;
-import android.widget.FrameLayout;
-import android.widget.OverScroller;
-
-import com.android.internal.R;
-
-import java.util.List;
-
-public class ScrollView 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;
-    private EdgeGlow mEdgeGlowTop;
-    private EdgeGlow mEdgeGlowBottom;
-
-    /**
-     * 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.
-     */
-    private 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;
-    private 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;
-
-    public ScrollView(Context context) {
-        this(context, null);
-    }
-
-    public ScrollView(Context context, AttributeSet attrs) {
-        this(context, attrs, com.android.internal.R.attr.scrollViewStyle);
-    }
-
-    public ScrollView(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();
-    }
-
-    @Override
-    public boolean shouldDelayChildPressedState() {
-        return true;
-    }
-
-    @Override
-    protected float getTopFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-
-        final int length = getVerticalFadingEdgeLength();
-        if (mScrollY < length) {
-            return mScrollY / (float) length;
-        }
-
-        return 1.0f;
-    }
-
-    @Override
-    protected float getBottomFadingEdgeStrength() {
-        if (getChildCount() == 0) {
-            return 0.0f;
-        }
-
-        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 * (mBottom - mTop));
-    }
-
-
-    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();
-    }
-
-    @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) {
-            int childHeight = child.getHeight();
-            return getHeight() < childHeight + 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);
-            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;
-    }
-
-    @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;
-        }
-
-        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 = ev.getY(pointerIndex);
-                final int yDiff = (int) Math.abs(y - mLastMotionY);
-                if (yDiff > mTouchSlop) {
-                    mIsBeingDragged = true;
-                    mLastMotionY = y;
-                    if (mScrollStrictSpan == null) {
-                        mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
-                    }
-                }
-                break;
-            }
-
-            case MotionEvent.ACTION_DOWN: {
-                final float y = ev.getY();
-                if (!inChild((int) ev.getX(), (int) y)) {
-                    mIsBeingDragged = false;
-                    break;
-                }
-
-                /*
-                 * Remember location of down touch.
-                 * ACTION_DOWN always refers to pointer index 0.
-                 */
-                mLastMotionY = y;
-                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 = !mScroller.isFinished();
-                if (mIsBeingDragged && mScrollStrictSpan == null) {
-                    mScrollStrictSpan = StrictMode.enterCriticalSpan("ScrollView-scroll");
-                }
-                break;
-            }
-
-            case MotionEvent.ACTION_CANCEL:
-            case MotionEvent.ACTION_UP:
-                /* Release the drag */
-                mIsBeingDragged = false;
-                mActivePointerId = INVALID_POINTER;
-                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;
-    }
-
-    @Override
-    public boolean onTouchEvent(MotionEvent ev) {
-
-        if (ev.getAction() == MotionEvent.ACTION_DOWN && ev.getEdgeFlags() != 0) {
-            // Don't handle edge touches immediately -- they may actually belong to one of our
-            // descendants.
-            return false;
-        }
-
-        if (mVelocityTracker == null) {
-            mVelocityTracker = VelocityTracker.obtain();
-        }
-        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 = ev.getY();
-                mActivePointerId = ev.getPointerId(0);
-                break;
-            }
-            case MotionEvent.ACTION_MOVE:
-                if (mIsBeingDragged) {
-                    // Scroll to follow the motion event
-                    final int activePointerIndex = ev.findPointerIndex(mActivePointerId);
-                    final float y = ev.getY(activePointerIndex);
-                    final int deltaY = (int) (mLastMotionY - y);
-                    mLastMotionY = y;
-
-                    final int oldX = mScrollX;
-                    final int oldY = mScrollY;
-                    final int range = getScrollRange();
-                    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 = oldY + deltaY;
-                        if (pulledToY < 0) {
-                            mEdgeGlowTop.onPull((float) deltaY / getHeight());
-                            if (!mEdgeGlowBottom.isFinished()) {
-                                mEdgeGlowBottom.onRelease();
-                            }
-                        } else if (pulledToY > range) {
-                            mEdgeGlowBottom.onPull((float) deltaY / getHeight());
-                            if (!mEdgeGlowTop.isFinished()) {
-                                mEdgeGlowTop.onRelease();
-                            }
-                        }
-                        if (mEdgeGlowTop != null
-                                && (!mEdgeGlowTop.isFinished() || !mEdgeGlowBottom.isFinished())) {
-                            invalidate();
-                        }
-                    }
-                }
-                break;
-            case MotionEvent.ACTION_UP:
-                if (mIsBeingDragged) {
-                    final VelocityTracker velocityTracker = mVelocityTracker;
-                    velocityTracker.computeCurrentVelocity(1000, mMaximumVelocity);
-                    int initialVelocity = (int) velocityTracker.getYVelocity(mActivePointerId);
-
-                    if (getChildCount() > 0) {
-                        if ((Math.abs(initialVelocity) > mMinimumVelocity)) {
-                            fling(-initialVelocity);
-                        } else {
-                            final int bottom = getScrollRange();
-                            if (mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, bottom)) {
-                                invalidate();
-                            }
-                        }
-                    }
-
-                    mActivePointerId = INVALID_POINTER;
-                    endDrag();
-                }
-                break;
-            case MotionEvent.ACTION_CANCEL:
-                if (mIsBeingDragged && getChildCount() > 0) {
-                    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 = ev.getY(index);
-                mLastMotionY = y;
-                mActivePointerId = ev.getPointerId(index);
-                break;
-            }
-            case MotionEvent.ACTION_POINTER_UP:
-                onSecondaryPointerUp(ev);
-                mLastMotionY = ev.getY(ev.findPointerIndex(mActivePointerId));
-                break;
-        }
-        return true;
-    }
-
-    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 = ev.getY(newPointerIndex);
-            mActivePointerId = ev.getPointerId(newPointerIndex);
-            if (mVelocityTracker != null) {
-                mVelocityTracker.clear();
-            }
-        }
-    }
-
-    @Override
-    public boolean onGenericMotionEvent(MotionEvent event) {
-        if ((event.getSource() & InputDevice.SOURCE_CLASS_POINTER) != 0) {
-            switch (event.getAction()) {
-                case MotionEvent.ACTION_SCROLL: {
-                    if (!mIsBeingDragged) {
-                        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);
-    }
-
-    @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 (clampedY) {
-                mScroller.springBack(mScrollX, mScrollY, 0, 0, 0, getScrollRange());
-            }
-        } else {
-            super.scrollTo(scrollX, scrollY);
-        }
-        awakenScrollBars();
-    }
-
-    private int getScrollRange() {
-        int scrollRange = 0;
-        if (getChildCount() > 0) {
-            View child = getChildAt(0);
-            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 = getVerticalFadingEdgeLength() / 2;
-        final int topWithoutFadingEdge = top + fadingEdgeLength;
-        final int bottomWithoutFadingEdge = top + getHeight() - fadingEdgeLength;
-
-        if ((preferredFocusable != null)
-                && (preferredFocusable.getTop() < bottomWithoutFadingEdge)
-                && (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 = view.getTop();
-            int viewBottom = 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 boolean viewIsCloserToBoundary =
-                            (topFocus && viewTop < focusCandidate.getTop()) ||
-                                    (!topFocus && viewBottom > focusCandidate
-                                            .getBottom());
-
-                    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;
-    }
-
-    /**
-     * <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;
-    }
-
-    /**
-     * @return whether the descendant of this scroll view is scrolled off
-     *  screen.
-     */
-    private boolean isOffScreen(View descendant) {
-        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);
-
-        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) {
-                smoothScrollBy(0, delta);
-            } else {
-                scrollBy(0, delta);
-            }
-        }
-    }
-
-    /**
-     * 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) {
-            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() {
-        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;
-    }
-
-    @Override
-    protected int computeVerticalScrollOffset() {
-        return Math.max(0, super.computeVerticalScrollOffset());
-    }
-
-    @Override
-    protected void measureChild(View child, int parentWidthMeasureSpec, int parentHeightMeasureSpec) {
-        ViewGroup.LayoutParams lp = child.getLayoutParams();
-
-        int childWidthMeasureSpec;
-        int childHeightMeasureSpec;
-
-        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();
-
-        final int childWidthMeasureSpec = getChildMeasureSpec(parentWidthMeasureSpec,
-                mPaddingLeft + mPaddingRight + lp.leftMargin + lp.rightMargin
-                        + widthUsed, lp.width);
-        final int 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) {
-                overScrollBy(x - oldX, y - oldY, oldX, oldY, 0, getScrollRange(),
-                        0, mOverflingDistance, false);
-                onScrollChanged(mScrollX, mScrollY, oldX, oldY);
-
-                final int range = getScrollRange();
-                final int overscrollMode = getOverScrollMode();
-                if (overscrollMode == OVER_SCROLL_ALWAYS ||
-                        (overscrollMode == OVER_SCROLL_IF_CONTENT_SCROLLS && range > 0)) {
-                    if (y < 0 && oldY >= 0) {
-                        mEdgeGlowTop.onAbsorb((int) mScroller.getCurrVelocity());
-                    } else if (y > range && oldY <= range) {
-                        mEdgeGlowBottom.onAbsorb((int) mScroller.getCurrVelocity());
-                    }
-                }
-            }
-            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);
-
-        int scrollDelta = computeScrollDeltaToGetChildRectOnScreen(mTempRect);
-
-        if (scrollDelta != 0) {
-            scrollBy(0, scrollDelta);
-        }
-    }
-
-    /**
-     * 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) {
-                scrollBy(0, delta);
-            } 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 (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;
-    }
-
-    @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 (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) {
-            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);
-
-            final boolean movingDown = velocityY > 0;
-
-            View currentFocused = findFocus();
-            View newFocused =
-                    findFocusableViewInMyBounds(movingDown, mScroller.getFinalY(), currentFocused);
-            if (newFocused == null) {
-                newFocused = this;
-            }
-
-            if (newFocused != currentFocused) {
-                    newFocused.requestFocus(movingDown ? View.FOCUS_DOWN : View.FOCUS_UP);
-            }
-
-            if (mFlingStrictSpan == null) {
-                mFlingStrictSpan = StrictMode.enterCriticalSpan("ScrollView-fling");
-            }
-
-            invalidate();
-        }
-    }
-
-    private void endDrag() {
-        mIsBeingDragged = false;
-
-        if (mVelocityTracker != null) {
-            mVelocityTracker.recycle();
-            mVelocityTracker = null;
-        }
-
-        if (mEdgeGlowTop != null) {
-            mEdgeGlowTop.onRelease();
-            mEdgeGlowBottom.onRelease();
-        }
-
-        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);
-            }
-        }
-    }
-
-    @Override
-    public void setOverScrollMode(int mode) {
-        if (mode != OVER_SCROLL_NEVER) {
-            if (mEdgeGlowTop == null) {
-                Context context = getContext();
-                final Resources res = context.getResources();
-                final Drawable edge = res.getDrawable(R.drawable.overscroll_edge);
-                final Drawable glow = res.getDrawable(R.drawable.overscroll_glow);
-                mEdgeGlowTop = new EdgeGlow(context, edge, glow);
-                mEdgeGlowBottom = new EdgeGlow(context, edge, glow);
-            }
-        } else {
-            mEdgeGlowTop = null;
-            mEdgeGlowBottom = null;
-        }
-        super.setOverScrollMode(mode);
-    }
-
-    @Override
-    public void draw(Canvas canvas) {
-        super.draw(canvas);
-        if (mEdgeGlowTop != null) {
-            final int scrollY = mScrollY;
-            if (!mEdgeGlowTop.isFinished()) {
-                final int restoreCount = canvas.save();
-                final int width = getWidth() - mPaddingLeft - mPaddingRight;
-
-                canvas.translate(mPaddingLeft, Math.min(0, scrollY));
-                mEdgeGlowTop.setSize(width, getHeight());
-                if (mEdgeGlowTop.draw(canvas)) {
-                    invalidate();
-                }
-                canvas.restoreToCount(restoreCount);
-            }
-            if (!mEdgeGlowBottom.isFinished()) {
-                final int restoreCount = canvas.save();
-                final int width = getWidth() - mPaddingLeft - mPaddingRight;
-                final int height = getHeight();
-
-                canvas.translate(-width + mPaddingLeft,
-                        Math.max(getScrollRange(), scrollY) + height);
-                canvas.rotate(180, width, 0);
-                mEdgeGlowBottom.setSize(width, height);
-                if (mEdgeGlowBottom.draw(canvas)) {
-                    invalidate();
-                }
-                canvas.restoreToCount(restoreCount);
-            }
-        }
-    }
-
-    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;
-    }
-}
