diff --git a/src/com/android/browser/Controller.java b/src/com/android/browser/Controller.java
index e20a876..ee40a93 100644
--- a/src/com/android/browser/Controller.java
+++ b/src/com/android/browser/Controller.java
@@ -16,12 +16,6 @@
 
 package com.android.browser;
 
-import com.android.browser.IntentHandler.UrlData;
-import com.android.browser.UI.DropdownChangeListener;
-import com.android.browser.provider.BrowserProvider;
-import com.android.browser.search.SearchEngine;
-import com.android.common.Search;
-
 import android.app.Activity;
 import android.app.DownloadManager;
 import android.app.SearchManager;
@@ -81,6 +75,12 @@
 import android.webkit.WebView;
 import android.widget.Toast;
 
+import com.android.browser.IntentHandler.UrlData;
+import com.android.browser.UI.DropdownChangeListener;
+import com.android.browser.provider.BrowserProvider;
+import com.android.browser.search.SearchEngine;
+import com.android.common.Search;
+
 import java.io.ByteArrayOutputStream;
 import java.io.File;
 import java.net.URLEncoder;
@@ -1242,8 +1242,8 @@
         }
     }
 
-    protected void onMenuKey() {
-        mUi.onMenuKey();
+    protected boolean onMenuKey() {
+        return mUi.onMenuKey();
     }
 
     // menu handling and state
@@ -2465,8 +2465,12 @@
         // Even if MENU is already held down, we need to call to super to open
         // the IME on long press.
         if (KeyEvent.KEYCODE_MENU == keyCode) {
-            event.startTracking();
-            return true;
+            if (mOptionsMenuHandler != null) {
+                return false;
+            } else {
+                event.startTracking();
+                return true;
+            }
         }
         if (!noModifiers
                 && ((KeyEvent.KEYCODE_MENU == keyCode)
@@ -2594,8 +2598,7 @@
         if (KeyEvent.KEYCODE_MENU == keyCode) {
             mMenuIsDown = false;
             if (event.isTracking() && !event.isCanceled()) {
-                onMenuKey();
-                return true;
+                return onMenuKey();
             }
         }
         if (!event.hasNoModifiers()) return false;
diff --git a/src/com/android/browser/NavScreen.java b/src/com/android/browser/NavScreen.java
index d872625..6ef759f 100644
--- a/src/com/android/browser/NavScreen.java
+++ b/src/com/android/browser/NavScreen.java
@@ -74,16 +74,6 @@
         init();
     }
 
-    @Override
-    public void onMeasure(int wspec, int hspec) {
-        super.onMeasure(wspec, hspec);
-    }
-
-    @Override
-    protected void onAttachedToWindow() {
-        mAdapter.notifyDataSetChanged();
-    }
-
     protected Tab getSelectedTab() {
         return (Tab) mScroller.getSelectedItem();
     }
@@ -268,66 +258,34 @@
 
         @Override
         public View getView(final int position, View convertView, ViewGroup parent) {
-            if (convertView == null) {
-                convertView = LayoutInflater.from(context).inflate(R.layout.nav_tab_view,
-                        null);
-            }
+            final NavTabView tabview = new NavTabView(mActivity);
             final Tab tab = getItem(position);
             final BrowserWebView web = (BrowserWebView) tab.getWebView();
-            removeFromParent(web);
-            FrameLayout mview = (FrameLayout) convertView.findViewById(R.id.tab_view);
-            mview.addView(web, 0);
-            ImageButton close = (ImageButton) convertView.findViewById(R.id.closetab);
-            close.setOnClickListener(new OnClickListener() {
+            tabview.setWebView(mUi, tab);
+            tabview.setOnClickListener(new OnClickListener() {
                 @Override
                 public void onClick(View v) {
-                    onCloseTab((Tab) (mScroller.getSelectedItem()));
-                }
-            });
-            web.setNavMode(true);
-            web.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mScroller.setSelection(position);
-                    close();
-                }
-            });
-            ImageButton forward = (ImageButton) convertView.findViewById(R.id.forward);
-            ImageButton refresh = (ImageButton) convertView.findViewById(R.id.refresh);
-            TextView title = (TextView) convertView.findViewById(R.id.title);
-            ImageView favicon = (ImageView) convertView.findViewById(R.id.favicon);
-            if (web != null) {
-                forward.setVisibility(web.canGoForward()
-                        ? View.VISIBLE : View.GONE);
-            }
-            // refresh titlebar
-            favicon.setImageDrawable(mUi.getFaviconDrawable(tab.getFavicon()));
-            title.setText(tab.getUrl());
-            title.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mUi.getTitleBar().setSkipTitleBarAnimations(true);
-                    close(false);
-                    mUi.editUrl(false);
-                    mUi.getTitleBar().setSkipTitleBarAnimations(false);
-                }
-            });
-            forward.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mUi.hideNavScreen(true);
-                    web.goForward();
-                }
-            });
-            refresh.setOnClickListener(new OnClickListener() {
-                @Override
-                public void onClick(View v) {
-                    mUi.hideNavScreen(true);
-                    web.reload();
-                }
-            });
+                    if (tabview.isRefresh(v)) {
+                        mUi.hideNavScreen(true);
+                        web.reload();
+                    } else 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();
 
-            return convertView;
+                    }
+                }
+            });
+            return tabview;
         }
 
     }
@@ -391,10 +349,5 @@
 
     }
 
-    private static void removeFromParent(View v) {
-        if (v.getParent() != null) {
-            ((ViewGroup) v.getParent()).removeView(v);
-        }
-    }
 
 }
diff --git a/src/com/android/browser/NavTabScroller.java b/src/com/android/browser/NavTabScroller.java
index dc5627a..cbb2cfd 100644
--- a/src/com/android/browser/NavTabScroller.java
+++ b/src/com/android/browser/NavTabScroller.java
@@ -16,28 +16,29 @@
 
 package com.android.browser;
 
-import com.android.browser.view.HorizontalScrollView;
-
 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 HorizontalScrollView {
-
-    private static final float DEFAULT_ALPHA = 0.5f;
+public class NavTabScroller extends FrameLayout {
 
     private LinearLayout mContentView;
-    private int mSelected;
     private BaseAdapter mAdapter;
-    private boolean mSnapScroll;
+    private SelectableSroller mScroller;
+    private int mOrientation;
 
     public NavTabScroller(Context context, AttributeSet attrs, int defStyle) {
         super(context, attrs, defStyle);
@@ -55,15 +56,14 @@
     }
 
     private void init(Context ctx) {
-        setHorizontalScrollBarEnabled(false);
-        mContentView = new LinearLayout(ctx);
-        mContentView.setOrientation(LinearLayout.HORIZONTAL);
-        int pad = ctx.getResources().getDimensionPixelSize(R.dimen.nav_scroller_padding);
-        mContentView.setPadding(pad, 0, pad, 0);
-        mContentView.setLayoutParams(
-                new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.MATCH_PARENT));
-        addView(mContentView);
-        mSelected = -1;
+        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);
     }
 
     protected void setAdapter(BaseAdapter adapter) {
@@ -85,24 +85,15 @@
     }
 
     protected void setSelection(int ix) {
-        mSelected = ix;
-        updateViewAlpha();
-    }
-
-    private void updateViewAlpha() {
-        final int n = mContentView.getChildCount();
-        for (int i = 0; i < n; i ++) {
-            View v = mContentView.getChildAt(i);
-            v.setAlpha((i == mSelected) ? 1.0f : DEFAULT_ALPHA);
-        }
+        mScroller.setSelection(ix);
     }
 
     protected int getSelectionIndex() {
-        return mSelected;
+        return mScroller.getSelection();
     }
 
     protected Tab getSelectedItem() {
-        return (Tab) mAdapter.getItem(mSelected);
+        return (Tab) mAdapter.getItem(mScroller.getSelection());
     }
 
     protected ViewGroup getContentView() {
@@ -110,77 +101,265 @@
     }
 
     private void populateList() {
-        clearTabs();
+        mContentView.removeAllViewsInLayout();
         for (int i = 0; i < mAdapter.getCount(); i++) {
-            View v = mAdapter.getView(i, null, mContentView);
+            NavTabView v = (NavTabView) mAdapter.getView(i, null, mContentView);
             mContentView.addView(v);
-            v.setAlpha((i == mSelected) ? 1.0f : DEFAULT_ALPHA);
         }
     }
 
     View getSelectedTab() {
-        if ((mSelected >= 0) && (mSelected < mContentView.getChildCount())) {
-            return mContentView.getChildAt(mSelected);
+        int selected = mScroller.getSelection();
+        if ((selected >= 0) && (selected < mContentView.getChildCount())) {
+            return mContentView.getChildAt(selected);
         } else {
             return null;
         }
     }
 
-    void clearTabs() {
-        for (int i = 0; i < mContentView.getChildCount(); i++) {
-            ViewGroup vg = (ViewGroup) mContentView.getChildAt(i);
-            vg.removeViewAt(0);
-        }
-        mContentView.removeAllViews();
+    static interface SelectableSroller {
+        void setSelection(int index);
+        int getSelection();
+        LinearLayout getContentView();
+
     }
 
-    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;
+    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);
+            int pad = ctx.getResources().getDimensionPixelSize(R.dimen.nav_scroller_padding);
+            mContentView.setPadding(0, pad, 0, pad);
+            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++) {
+                View child = mContentView.getChildAt(i);
+                if (child.getTop() <= midy && child.getBottom() >= midy) {
+                    sel = i;
+                    break;
+                }
+            }
+            if (sel != -1) {
+                if (sel != mSelected) {
+                    setSelection(sel);
+                }
+                if (!isCentered(mSelected)) {
+                    NavTabView ntv = (NavTabView) getSelectedView();
+                    ntv.setHighlighted(false);
+                }
             }
         }
-        if (sel != -1 && sel != mSelected) {
-            setSelection(sel);
-        }
-    }
 
-    @Override
-    public boolean onTouchEvent(MotionEvent evt) {
-        boolean dragged = mIsBeingDragged;
-        boolean result = super.onTouchEvent(evt);
-        if (MotionEvent.ACTION_UP == evt.getActionMasked()) {
-            if (mScroller.isFinished() && dragged) {
-                snapToSelected();
+        @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();
+                }
+            }
+            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(isCentered(mSelected));
+                }
             }
         }
-        return result;
-    }
 
-    @Override
-    public void computeScroll() {
-        super.computeScroll();
-        if (mScroller.isFinished() && !mIsBeingDragged) {
-            if (!mSnapScroll) {
-                snapToSelected();
-            } else {
-                // reset snap scrolling flag
-                mSnapScroll = false;
+        private boolean isCentered(int ix) {
+            int midy = getScrollY() + (getTop() + getBottom()) / 2;
+            View v = mContentView.getChildAt(ix);
+            return (v.getTop() + v.getBottom()) / 2 == midy;
+        }
+
+        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);
             }
         }
+
+        protected View getSelectedView() {
+            return mContentView.getChildAt(mSelected);
+        }
+
     }
 
-    private void snapToSelected() {
-        // snap to selected
-        mSnapScroll = true;
-        View v = mContentView.getChildAt(mSelected);
-        int left = (v.getLeft() + v.getRight()) / 2;
-        left -= getWidth() / 2;
-        scrollTo(left,0);
+    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);
+            int pad = ctx.getResources().getDimensionPixelSize(R.dimen.nav_scroller_padding);
+            mContentView.setPadding(pad, 0, pad, 0);
+            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);
+                }
+                if (!isCentered(mSelected)) {
+                    NavTabView ntv = (NavTabView) getSelectedView();
+                    ntv.setHighlighted(false);
+                }
+            }
+        }
+
+        @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();
+                }
+            }
+            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(isCentered(mSelected));
+                }
+            }
+        }
+
+        private boolean isCentered(int ix) {
+            int midx = getScrollX() + getWidth() / 2;
+            View v = mContentView.getChildAt(ix);
+            return (v.getLeft() + v.getRight()) / 2 == midx;
+        }
+
+        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);
+            }
+        }
+
+        protected View getSelectedView() {
+            return mContentView.getChildAt(mSelected);
+        }
+
     }
 
 }
diff --git a/src/com/android/browser/NavTabView.java b/src/com/android/browser/NavTabView.java
new file mode 100644
index 0000000..14453dc
--- /dev/null
+++ b/src/com/android/browser/NavTabView.java
@@ -0,0 +1,175 @@
+/*
+ * 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.graphics.drawable.Drawable;
+import android.util.AttributeSet;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+public class NavTabView extends LinearLayout {
+
+    Tab mTab;
+    BrowserWebView mWebView;
+    ImageButton mForward;
+    ImageButton mRefresh;
+    ImageView mFavicon;
+    ImageButton mClose;
+    FrameLayout mContainer;
+    TextView mTitle;
+    View mTitleBar;
+    OnClickListener mClickListener;
+    boolean mHighlighted;
+    Drawable mTitleBg;
+
+    public NavTabView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+        init();
+    }
+
+    public NavTabView(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        init();
+    }
+
+    public NavTabView(Context context) {
+        super(context);
+        init();
+    }
+
+    private void init() {
+        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);
+        mTitle = (TextView) findViewById(R.id.title);
+        mFavicon = (ImageView) findViewById(R.id.favicon);
+        mTitleBar = findViewById(R.id.titlebar);
+        mTitleBg = mContext.getResources().getDrawable(R.drawable.bg_urlbar);
+        setState(false);
+        // refresh titlebar
+    }
+
+    protected boolean isRefresh(View v) {
+        return v == mRefresh;
+    }
+
+    protected boolean isClose(View v) {
+        return v == mClose;
+    }
+
+    protected boolean isTitle(View v) {
+        return v == mTitleBar;
+    }
+
+    protected boolean isForward(View v) {
+        return v == mForward;
+    }
+
+    protected boolean isWebView(View v) {
+        return v == mWebView;
+    }
+
+    protected void setHighlighted(boolean highlighted) {
+        if (highlighted == mHighlighted) return;
+        mHighlighted = highlighted;
+        setState(highlighted);
+    }
+
+    private void setState(boolean highlighted) {
+        if (highlighted) {
+            setAlpha(1.0f);
+            mRefresh.setVisibility(View.VISIBLE);
+            mFavicon.setVisibility(View.VISIBLE);
+            mForward.setVisibility(mWebView.canGoForward()
+                    ? View.VISIBLE : View.GONE);
+            mTitleBar.setBackgroundDrawable(mTitleBg);
+            mClose.setVisibility(View.VISIBLE);
+        } else {
+            setAlpha(0.8f);
+            mForward.setVisibility(View.GONE);
+            mRefresh.setVisibility(View.INVISIBLE);
+            mFavicon.setVisibility(View.INVISIBLE);
+            mClose.setVisibility(View.GONE);
+            mTitleBar.setBackgroundDrawable(null);
+        }
+        setTitle();
+    }
+
+    private void setTitle() {
+        if (mTab == null) return;
+        if (mHighlighted) {
+            mTitle.setText(mTab.getUrl());
+        } else {
+            String txt = mTab.getTitle();
+            if (txt == null) txt = mTab.getUrl();
+            mTitle.setText(txt);
+        }
+    }
+
+    protected boolean isHighlighted() {
+        return mHighlighted;
+    }
+
+    protected void setWebView(PhoneUi ui, Tab tab) {
+        mTab = tab;
+        BrowserWebView web = (BrowserWebView) tab.getWebView();
+        if (web == null) return;
+        mWebView = web;
+        removeFromParent(mWebView);
+        mWebView.setNavMode(true);
+        mContainer.addView(mWebView, 0);
+        if (mWebView != null) {
+            mForward.setVisibility(mWebView.canGoForward()
+                    ? View.VISIBLE : View.GONE);
+        }
+        mFavicon.setImageDrawable(ui.getFaviconDrawable(tab.getFavicon()));
+        setTitle();
+    }
+
+    protected void hideTitle() {
+        mTitleBar.setVisibility(View.INVISIBLE);
+    }
+
+    @Override
+    public void setOnClickListener(OnClickListener listener) {
+        mClickListener = listener;
+        mTitleBar.setOnClickListener(mClickListener);
+        mRefresh.setOnClickListener(mClickListener);
+        mForward.setOnClickListener(mClickListener);
+        mClose.setOnClickListener(mClickListener);
+        if (mWebView != null) {
+            mWebView.setOnClickListener(mClickListener);
+        }
+    }
+
+    private static void removeFromParent(View v) {
+        if (v.getParent() != null) {
+            ((ViewGroup) v.getParent()).removeView(v);
+        }
+    }
+
+}
diff --git a/src/com/android/browser/PhoneUi.java b/src/com/android/browser/PhoneUi.java
index 80fdcfa..ce993fd 100644
--- a/src/com/android/browser/PhoneUi.java
+++ b/src/com/android/browser/PhoneUi.java
@@ -17,6 +17,7 @@
 package com.android.browser;
 
 import android.app.Activity;
+import android.os.Bundle;
 import android.util.Log;
 import android.view.ActionMode;
 import android.view.Gravity;
@@ -107,12 +108,16 @@
 
     @Override
     public boolean onMenuKey() {
-        if (mNavScreen == null) {
-            showNavScreen();
+        if (!isComboViewShowing()) {
+            if (mNavScreen == null) {
+                showNavScreen();
+            } else {
+                mNavScreen.close();
+            }
+            return true;
         } else {
-            mNavScreen.close();
+            return false;
         }
-        return true;
     }
 
     @Override
@@ -210,6 +215,14 @@
     }
 
     @Override
+    public void showComboView(boolean startWithHistory, Bundle extras) {
+        if (mNavScreen != null) {
+            hideNavScreen(false);
+        }
+        super.showComboView(startWithHistory, extras);
+    }
+
+    @Override
     public boolean showsWeb() {
         return super.showsWeb() && mActiveTabsPage == null;
     }
@@ -283,15 +296,12 @@
     @Override
     protected void captureTab(final Tab tab) {
         if (tab == null) return;
-        if (mUseQuickControls) {
-            super.captureTab(tab);
-        } else {
-            BrowserWebView web = (BrowserWebView) tab.getWebView();
-            if (web != null) {
-                tab.setScreenshot(web.capture());
-            }
+        BrowserWebView web = (BrowserWebView) tab.getWebView();
+        if (web != null) {
+            tab.setScreenshot(web.capture());
         }
     }
+
     void showNavScreen() {
         detachTab(mActiveTab);
         mNavScreen = new NavScreen(mActivity, mUiController, this);
diff --git a/src/com/android/browser/view/ScrollView.java b/src/com/android/browser/view/ScrollView.java
new file mode 100644
index 0000000..ab09a8c
--- /dev/null
+++ b/src/com/android/browser/view/ScrollView.java
@@ -0,0 +1,1538 @@
+/*
+ * 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;
+    }
+}
