diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
new file mode 100644
index 0000000..cf3fe70
--- /dev/null
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.net.ParseException;
+import android.net.WebAddress;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.view.View;
+import android.view.Window;
+import android.webkit.WebIconDatabase;
+import android.widget.EditText;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Date;
+
+public class AddBookmarkPage extends Activity {
+
+    private final String LOGTAG = "Bookmarks";
+
+    private EditText    mTitle;
+    private EditText    mAddress;
+    private TextView    mButton;
+    private View        mCancelButton;
+    private boolean     mEditingExisting;
+    private Bundle      mMap;
+    
+    private static final String[]   mProjection = 
+        { "_id", "url", "bookmark", "created", "title", "visits" };
+    private static final String     WHERE_CLAUSE = "url = ?";
+    private final String[]          SELECTION_ARGS = new String[1];
+
+    private View.OnClickListener mSaveBookmark = new View.OnClickListener() {
+        public void onClick(View v) {
+            if (save()) {
+                finish();
+                Toast.makeText(AddBookmarkPage.this, R.string.bookmark_saved,
+                        Toast.LENGTH_LONG).show();
+            }
+        }
+    };
+
+    private View.OnClickListener mCancel = new View.OnClickListener() {
+        public void onClick(View v) {
+            finish();
+        }
+    };
+
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        requestWindowFeature(Window.FEATURE_LEFT_ICON);
+        setContentView(R.layout.browser_add_bookmark);
+        setTitle(R.string.save_to_bookmarks);
+        getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON, R.drawable.ic_dialog_bookmark);
+        
+        String title = null;
+        String url = null;
+        mMap = getIntent().getExtras();
+        if (mMap != null) {
+            Bundle b = mMap.getBundle("bookmark");
+            if (b != null) {
+                mMap = b;
+                mEditingExisting = true;
+                setTitle(R.string.edit_bookmark);
+            }
+            title = mMap.getString("title");
+            url = mMap.getString("url");
+        }
+
+        mTitle = (EditText) findViewById(R.id.title);
+        mTitle.setText(title);
+        mAddress = (EditText) findViewById(R.id.address);
+        mAddress.setText(url);
+
+
+        View.OnClickListener accept = mSaveBookmark;
+        mButton = (TextView) findViewById(R.id.OK);
+        mButton.setOnClickListener(accept);
+
+        mCancelButton = findViewById(R.id.cancel);
+        mCancelButton.setOnClickListener(mCancel);
+        
+        if (!getWindow().getDecorView().isInTouchMode()) {
+            mButton.requestFocus();
+        }
+    }
+    
+    /**
+     *  Save the data to the database. 
+     *  Also, change the view to dialog stating 
+     *  that the webpage has been saved.
+     */
+    boolean save() {
+        String title = mTitle.getText().toString().trim();
+        String unfilteredUrl = 
+                BrowserActivity.fixUrl(mAddress.getText().toString());
+        boolean emptyTitle = title.length() == 0;
+        boolean emptyUrl = unfilteredUrl.trim().length() == 0;
+        Resources r = getResources();
+        if (emptyTitle || emptyUrl) {
+            if (emptyTitle) {
+                mTitle.setError(r.getText(R.string.bookmark_needs_title));
+            }
+            if (emptyUrl) {
+                mAddress.setError(r.getText(R.string.bookmark_needs_url));
+            }
+            return false;
+        }
+        String url = unfilteredUrl;
+        if (!(url.startsWith("about:") || url.startsWith("data:") || url
+                .startsWith("file:"))) {
+            WebAddress address;
+            try {
+                address = new WebAddress(unfilteredUrl);
+            } catch (ParseException e) {
+                mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
+                return false;
+            }
+            if (address.mHost.length() == 0) {
+                mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
+                return false;
+            }
+            url = address.toString();
+        }
+        try {
+            if (mEditingExisting) {
+                mMap.putString("title", title);
+                mMap.putString("url", url);
+                setResult(RESULT_OK, (new Intent()).setAction(
+                        getIntent().toString()).putExtras(mMap));
+            } else {
+                // Want to append to the beginning of the list
+                long creationTime = new Date().getTime();
+                SELECTION_ARGS[0] = url;
+                ContentResolver cr = getContentResolver();
+                Cursor c = cr.query(Browser.BOOKMARKS_URI,
+                        mProjection,
+                        WHERE_CLAUSE,
+                        SELECTION_ARGS,
+                        null);
+                ContentValues map = new ContentValues();
+                if (c.moveToFirst() && c.getInt(c.getColumnIndexOrThrow(
+                        Browser.BookmarkColumns.BOOKMARK)) == 0) {
+                    // This means we have been to this site but not bookmarked
+                    // it, so convert the history item to a bookmark                    
+                    map.put(Browser.BookmarkColumns.CREATED, creationTime);
+                    map.put(Browser.BookmarkColumns.TITLE, title);
+                    map.put(Browser.BookmarkColumns.BOOKMARK, 1);
+                    cr.update(Browser.BOOKMARKS_URI, map, 
+                            "_id = " + c.getInt(0), null);
+                } else {
+                    int count = c.getCount();
+                    boolean matchedTitle = false;
+                    for (int i = 0; i < count; i++) {
+                        // One or more bookmarks already exist for this site.
+                        // Check the names of each
+                        c.moveToPosition(i);
+                        if (c.getString(c.getColumnIndexOrThrow(
+                                Browser.BookmarkColumns.TITLE)).equals(title)) {
+                            // The old bookmark has the same name.
+                            // Update its creation time.
+                            map.put(Browser.BookmarkColumns.CREATED,
+                                    creationTime);
+                            cr.update(Browser.BOOKMARKS_URI, map, 
+                                    "_id = " + c.getInt(0), null);
+                            matchedTitle = true;
+                        }
+                    }
+                    if (!matchedTitle) {
+                        // Adding a bookmark for a site the user has visited,
+                        // or a new bookmark (with a different name) for a site
+                        // the user has visited
+                        map.put(Browser.BookmarkColumns.TITLE, title);
+                        map.put(Browser.BookmarkColumns.URL, url);
+                        map.put(Browser.BookmarkColumns.CREATED, creationTime);
+                        map.put(Browser.BookmarkColumns.BOOKMARK, 1);
+                        map.put(Browser.BookmarkColumns.DATE, 0);
+                        int visits = 0;
+                        if (count > 0) {
+                            // The user has already bookmarked, and possibly
+                            // visited this site.  However, they are creating
+                            // a new bookmark with the same url but a different
+                            // name.  The new bookmark should have the same
+                            // number of visits as the already created bookmark.
+                            visits = c.getInt(c.getColumnIndexOrThrow(
+                                    Browser.BookmarkColumns.VISITS));
+                        }
+                        // Bookmark starts with 3 extra visits so that it will
+                        // bubble up in the most visited and goto search box
+                        map.put(Browser.BookmarkColumns.VISITS, visits + 3);
+                        cr.insert(Browser.BOOKMARKS_URI, map);
+                    }
+                }
+                WebIconDatabase.getInstance().retainIconForPageUrl(url);
+                c.deactivate();
+                setResult(RESULT_OK);
+            }
+        } catch (IllegalStateException e) {
+            setTitle(r.getText(R.string.no_database));
+            return false;
+        }
+        return true;
+    }
+}
diff --git a/src/com/android/browser/AddNewBookmark.java b/src/com/android/browser/AddNewBookmark.java
new file mode 100644
index 0000000..a75d002
--- /dev/null
+++ b/src/com/android/browser/AddNewBookmark.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 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.view.LayoutInflater;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ *  Custom layout for an item representing a bookmark in the browser.
+ */
+ // FIXME: Remove BrowserBookmarkItem
+class AddNewBookmark extends LinearLayout {
+
+    private TextView    mTextView;
+    private TextView    mUrlText;
+    private ImageView   mImageView;
+
+    /**
+     *  Instantiate a bookmark item, including a default favicon.
+     *
+     *  @param context  The application context for the item.
+     */
+    AddNewBookmark(Context context) {
+        super(context);
+
+        setWillNotDraw(false);
+        LayoutInflater factory = LayoutInflater.from(context);
+        factory.inflate(R.layout.add_new_bookmark, this);
+        mTextView = (TextView) findViewById(R.id.title);
+        mUrlText = (TextView) findViewById(R.id.url);
+        mImageView = (ImageView) findViewById(R.id.favicon);
+    }
+    
+    /**
+     *  Copy this BookmarkItem to item.
+     *  @param item BookmarkItem to receive the info from this BookmarkItem.
+     */
+    /* package */ void copyTo(AddNewBookmark item) {
+        item.mTextView.setText(mTextView.getText());
+        item.mUrlText.setText(mUrlText.getText());
+        item.mImageView.setImageDrawable(mImageView.getDrawable());
+    }
+    
+    /**
+     *  Set the new url for the bookmark item.
+     *  @param url  The new url for the bookmark item.
+     */
+    /* package */ void setUrl(String url) {
+        mUrlText.setText(url);
+    }
+}
diff --git a/src/com/android/browser/BookmarkItem.java b/src/com/android/browser/BookmarkItem.java
new file mode 100644
index 0000000..a70dd4f
--- /dev/null
+++ b/src/com/android/browser/BookmarkItem.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright (C) 2008 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.Bitmap;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ *  Custom layout for an item representing a bookmark in the browser.
+ */
+class BookmarkItem extends LinearLayout {
+
+    protected TextView    mTextView;
+    protected TextView    mUrlText;
+    protected ImageView   mImageView;
+    protected String      mUrl;
+
+    /**
+     *  Instantiate a bookmark item, including a default favicon.
+     *
+     *  @param context  The application context for the item.
+     */
+    BookmarkItem(Context context) {
+        super(context);
+
+        LayoutInflater factory = LayoutInflater.from(context);
+        factory.inflate(R.layout.history_item, this);
+        mTextView = (TextView) findViewById(R.id.title);
+        mUrlText = (TextView) findViewById(R.id.url);
+        mImageView = (ImageView) findViewById(R.id.favicon);
+        View star = findViewById(R.id.star);
+        star.setVisibility(View.GONE);
+    }
+
+    /**
+     *  Copy this BookmarkItem to item.
+     *  @param item BookmarkItem to receive the info from this BookmarkItem.
+     */
+    /* package */ void copyTo(BookmarkItem item) {
+        item.mTextView.setText(mTextView.getText());
+        item.mUrlText.setText(mUrlText.getText());
+        item.mImageView.setImageDrawable(mImageView.getDrawable());
+    }
+
+    /**
+     * Return the name assigned to this bookmark item.
+     */
+    /* package */ String getName() {
+        return mTextView.getText().toString();
+    }
+
+    /**
+     * Return the TextView which holds the name of this bookmark item.
+     */
+    /* package */ TextView getNameTextView() {
+        return mTextView;
+    }
+
+    /* package */ String getUrl() {
+        return mUrl;
+    }
+
+    /**
+     *  Set the favicon for this item.
+     *
+     *  @param b    The new bitmap for this item.
+     *              If it is null, will use the default.
+     */
+    /* package */ void setFavicon(Bitmap b) {
+        if (b != null) {
+            mImageView.setImageBitmap(b);
+        } else {
+            mImageView.setImageResource(R.drawable.app_web_browser_sm);
+        }
+    }
+
+    /**
+     *  Set the new name for the bookmark item.
+     *
+     *  @param name The new name for the bookmark item.
+     */
+    /* package */ void setName(String name) {
+        mTextView.setText(name);
+    }
+    
+    /**
+     *  Set the new url for the bookmark item.
+     *  @param url  The new url for the bookmark item.
+     */
+    /* package */ void setUrl(String url) {
+        mUrlText.setText(url);
+        mUrl = url;
+    }
+}
diff --git a/src/com/android/browser/Browser.java b/src/com/android/browser/Browser.java
new file mode 100644
index 0000000..32cee67
--- /dev/null
+++ b/src/com/android/browser/Browser.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.util.Config;
+import android.util.Log;
+
+import android.app.Application;
+import android.content.Intent;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+
+import dalvik.system.VMRuntime;
+
+public class Browser extends Application { 
+
+    private final static String LOGTAG = "browser";
+
+    /**
+     * Specifies a heap utilization ratio that works better
+     * for the browser than the default ratio does.
+     */
+    private final static float TARGET_HEAP_UTILIZATION = 0.75f;
+
+    public Browser() {
+    }
+
+    public void onCreate() {
+        if (Config.LOGV)
+            Log.v(LOGTAG, "Browser.onCreate: this=" + this);
+        // Fix heap utilization for better heap size characteristics.
+        VMRuntime.getRuntime().setTargetHeapUtilization(
+                TARGET_HEAP_UTILIZATION);
+        // create CookieSyncManager with current Context
+        CookieSyncManager.createInstance(this);
+        // remove all expired cookies
+        CookieManager.getInstance().removeExpiredCookie();
+    }
+
+    static Intent createBrowserViewIntent() {
+        Intent intent = new Intent(Intent.ACTION_WEB_SEARCH);
+        return intent;
+    }
+}
+
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
new file mode 100644
index 0000000..53640e5
--- /dev/null
+++ b/src/com/android/browser/BrowserActivity.java
@@ -0,0 +1,4567 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import com.google.android.googleapps.IGoogleLoginService;
+import com.google.android.googlelogin.GoogleLoginServiceConstants;
+
+import android.app.Activity;
+import android.app.ActivityManager;
+import android.app.AlertDialog;
+import android.app.ProgressDialog;
+import android.app.SearchManager;
+import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteException;
+import android.graphics.Bitmap;
+import android.graphics.Canvas;
+import android.graphics.Color;
+import android.graphics.DrawFilter;
+import android.graphics.Paint;
+import android.graphics.PaintFlagsDrawFilter;
+import android.graphics.Picture;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.PaintDrawable;
+import android.hardware.SensorListener;
+import android.hardware.SensorManager;
+import android.net.ConnectivityManager;
+import android.net.Uri;
+import android.net.WebAddress;
+import android.net.http.EventHandler;
+import android.net.http.SslCertificate;
+import android.net.http.SslError;
+import android.os.AsyncTask;
+import android.os.Bundle;
+import android.os.Debug;
+import android.os.Environment;
+import android.os.Handler;
+import android.os.IBinder;
+import android.os.Message;
+import android.os.PowerManager;
+import android.os.Process;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.preference.PreferenceManager;
+import android.provider.Browser;
+import android.provider.Contacts;
+import android.provider.Downloads;
+import android.provider.MediaStore;
+import android.provider.Contacts.Intents.Insert;
+import android.text.IClipboard;
+import android.text.TextUtils;
+import android.text.format.DateFormat;
+import android.text.util.Regex;
+import android.util.Config;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.MenuItem.OnMenuItemClickListener;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.DecelerateInterpolator;
+import android.view.animation.ScaleAnimation;
+import android.view.animation.TranslateAnimation;
+import android.webkit.CookieManager;
+import android.webkit.CookieSyncManager;
+import android.webkit.DownloadListener;
+import android.webkit.HttpAuthHandler;
+import android.webkit.SslErrorHandler;
+import android.webkit.URLUtil;
+import android.webkit.WebChromeClient;
+import android.webkit.WebHistoryItem;
+import android.webkit.WebIconDatabase;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.EditText;
+import android.widget.FrameLayout;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URL;
+import java.net.URLEncoder;
+import java.text.ParseException;
+import java.util.Date;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+public class BrowserActivity extends Activity
+    implements KeyTracker.OnKeyTracker,
+        View.OnCreateContextMenuListener,
+        DownloadListener {
+
+    private IGoogleLoginService mGls = null;
+    private ServiceConnection mGlsConnection = null;
+
+    private SensorManager mSensorManager = null;
+
+    /* Whitelisted webpages
+    private static HashSet<String> sWhiteList;
+
+    static {
+        sWhiteList = new HashSet<String>();
+        sWhiteList.add("cnn.com/");
+        sWhiteList.add("espn.go.com/");
+        sWhiteList.add("nytimes.com/");
+        sWhiteList.add("engadget.com/");
+        sWhiteList.add("yahoo.com/");
+        sWhiteList.add("msn.com/");
+        sWhiteList.add("amazon.com/");
+        sWhiteList.add("consumerist.com/");
+        sWhiteList.add("google.com/m/news");
+    }
+    */
+
+    private void setupHomePage() {
+        final Runnable getAccount = new Runnable() {
+            public void run() {
+                // Lower priority
+                Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+                // get the default home page
+                String homepage = mSettings.getHomePage();
+
+                try {
+                    if (mGls == null) return;
+
+                    String hostedUser = mGls.getAccount(GoogleLoginServiceConstants.PREFER_HOSTED);
+                    String googleUser = mGls.getAccount(GoogleLoginServiceConstants.REQUIRE_GOOGLE);
+
+                    // three cases:
+                    //
+                    //   hostedUser == googleUser
+                    //      The device has only a google account
+                    //
+                    //   hostedUser != googleUser
+                    //      The device has a hosted account and a google account
+                    //
+                    //   hostedUser != null, googleUser == null
+                    //      The device has only a hosted account (so far)
+
+                    // developers might have no accounts at all
+                    if (hostedUser == null) return;
+
+                    if (googleUser == null || !hostedUser.equals(googleUser)) {
+                        String domain = hostedUser.substring(hostedUser.lastIndexOf('@')+1);
+                        homepage = "http://www.google.com/m/a/" + domain + "?client=ms-" +
+                            SystemProperties.get("persist.sys.com.google.clientid", "unknown");
+                    }
+                } catch (RemoteException ignore) {
+                    // Login service died; carry on
+                } catch (RuntimeException ignore) {
+                    // Login service died; carry on
+                } finally {
+                    finish(homepage);
+                }
+            }
+
+            private void finish(final String homepage) {
+                mHandler.post(new Runnable() {
+                    public void run() {
+                        mSettings.setHomePage(BrowserActivity.this, homepage);
+                        resumeAfterCredentials();
+
+                        // as this is running in a separate thread,
+                        // BrowserActivity's onDestroy() may have been called,
+                        // which also calls unbindService().
+                        if (mGlsConnection != null) {
+                            // we no longer need to keep GLS open
+                            unbindService(mGlsConnection);
+                            mGlsConnection = null;
+                        }
+                    } });
+            } };
+
+        final boolean[] done = { false };
+
+        // Open a connection to the Google Login Service.  The first
+        // time the connection is established, set up the homepage depending on
+        // the account in a background thread.
+        mGlsConnection = new ServiceConnection() {
+            public void onServiceConnected(ComponentName className, IBinder service) {
+                mGls = IGoogleLoginService.Stub.asInterface(service);
+                if (done[0] == false) {
+                    done[0] = true;
+                    Thread account = new Thread(getAccount);
+                    account.setName("GLSAccount");
+                    account.start();
+                }
+            }
+            public void onServiceDisconnected(ComponentName className) {
+                mGls = null;
+            }
+        };
+
+        bindService(GoogleLoginServiceConstants.SERVICE_INTENT,
+                    mGlsConnection, Context.BIND_AUTO_CREATE);
+    }
+
+    /**
+     * This class is in charge of installing pre-packaged plugins
+     * from the Browser assets directory to the user's data partition.
+     * Plugins are loaded from the "plugins" directory in the assets;
+     * Anything that is in this directory will be copied over to the
+     * user data partition in app_plugins.
+     */
+    private class CopyPlugins implements Runnable {
+        final static String TAG = "PluginsInstaller";
+        final static String ZIP_FILTER = "assets/plugins/";
+        final static String APK_PATH = "/system/app/Browser.apk";
+        final static String PLUGIN_EXTENSION = ".so";
+        final static String TEMPORARY_EXTENSION = "_temp";
+        final static String BUILD_INFOS_FILE = "build.prop";
+        final static String SYSTEM_BUILD_INFOS_FILE = "/system/"
+                              + BUILD_INFOS_FILE;
+        final int BUFSIZE = 4096;
+        boolean mDoOverwrite = false;
+        String pluginsPath;
+        Context mContext;
+        File pluginsDir;
+        AssetManager manager;
+
+        public CopyPlugins (boolean overwrite, Context context) {
+            mDoOverwrite = overwrite;
+            mContext = context;
+        }
+
+        /**
+         * Returned a filtered list of ZipEntry.
+         * We list all the files contained in the zip and
+         * only returns the ones starting with the ZIP_FILTER
+         * path.
+         *
+         * @param zip the zip file used.
+         */
+        public Vector<ZipEntry> pluginsFilesFromZip(ZipFile zip) {
+            Vector<ZipEntry> list = new Vector<ZipEntry>();
+            Enumeration entries = zip.entries();
+            while (entries.hasMoreElements()) {
+                ZipEntry entry = (ZipEntry) entries.nextElement();
+                if (entry.getName().startsWith(ZIP_FILTER)) {
+                  list.add(entry);
+                }
+            }
+            return list;
+        }
+
+        /**
+         * Utility method to copy the content from an inputstream
+         * to a file output stream.
+         */
+        public void copyStreams(InputStream is, FileOutputStream fos) {
+            BufferedOutputStream os = null;
+            try {
+                byte data[] = new byte[BUFSIZE];
+                int count;
+                os = new BufferedOutputStream(fos, BUFSIZE);
+                while ((count = is.read(data, 0, BUFSIZE)) != -1) {
+                    os.write(data, 0, count);
+                }
+                os.flush();
+            } catch (IOException e) {
+                Log.e(TAG, "Exception while copying: " + e);
+            } finally {
+              try {
+                if (os != null) {
+                    os.close();
+                }
+              } catch (IOException e2) {
+                Log.e(TAG, "Exception while closing the stream: " + e2);
+              }
+            }
+        }
+
+        /**
+         * Returns a string containing the contents of a file
+         *
+         * @param file the target file
+         */
+        private String contentsOfFile(File file) {
+          String ret = null;
+          FileInputStream is = null;
+          try {
+            byte[] buffer = new byte[BUFSIZE];
+            int count;
+            is = new FileInputStream(file);
+            StringBuffer out = new StringBuffer();
+
+            while ((count = is.read(buffer, 0, BUFSIZE)) != -1) {
+              out.append(new String(buffer, 0, count));
+            }
+            ret = out.toString();
+          } catch (IOException e) {
+            Log.e(TAG, "Exception getting contents of file " + e);
+          } finally {
+            if (is != null) {
+              try {
+                is.close();
+              } catch (IOException e2) {
+                Log.e(TAG, "Exception while closing the file: " + e2);
+              }
+            }
+          }
+          return ret;
+        }
+
+        /**
+         * Utility method to initialize the user data plugins path.
+         */
+        public void initPluginsPath() {
+            BrowserSettings s = BrowserSettings.getInstance();
+            pluginsPath = s.getPluginsPath();
+            if (pluginsPath == null) {
+                s.loadFromDb(mContext);
+                pluginsPath = s.getPluginsPath();
+            }
+            if (Config.LOGV) {
+                Log.v(TAG, "Plugin path: " + pluginsPath);
+            }
+        }
+
+        /**
+         * Utility method to delete a file or a directory
+         *
+         * @param file the File to delete
+         */
+        public void deleteFile(File file) {
+            File[] files = file.listFiles();
+            if ((files != null) && files.length > 0) {
+              for (int i=0; i< files.length; i++) {
+                deleteFile(files[i]);
+              }
+            }
+            if (!file.delete()) {
+              Log.e(TAG, file.getPath() + " could not get deleted");
+            }
+        }
+
+        /**
+         * Clean the content of the plugins directory.
+         * We delete the directory, then recreate it.
+         */
+        public void cleanPluginsDirectory() {
+          if (Config.LOGV) {
+            Log.v(TAG, "delete plugins directory: " + pluginsPath);
+          }
+          File pluginsDirectory = new File(pluginsPath);
+          deleteFile(pluginsDirectory);
+          pluginsDirectory.mkdir();
+        }
+
+
+        /**
+         * Copy the SYSTEM_BUILD_INFOS_FILE file containing the
+         * informations about the system build to the
+         * BUILD_INFOS_FILE in the plugins directory.
+         */
+        public void copyBuildInfos() {
+          try {
+            if (Config.LOGV) {
+              Log.v(TAG, "Copy build infos to the plugins directory");
+            }
+            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
+            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
+            copyStreams(new FileInputStream(buildInfoFile),
+                        new FileOutputStream(buildInfoPlugins));
+          } catch (IOException e) {
+            Log.e(TAG, "Exception while copying the build infos: " + e);
+          }
+        }
+
+        /**
+         * Returns true if the current system is newer than the
+         * system that installed the plugins.
+         * We determinate this by checking the build number of the system.
+         *
+         * At the end of the plugins copy operation, we copy the
+         * SYSTEM_BUILD_INFOS_FILE to the BUILD_INFOS_FILE.
+         * We then just have to load both and compare them -- if they
+         * are different the current system is newer.
+         *
+         * Loading and comparing the strings should be faster than
+         * creating a hash, the files being rather small. Extracting the
+         * version number would require some parsing which may be more
+         * brittle.
+         */
+        public boolean newSystemImage() {
+          try {
+            File buildInfoFile = new File(SYSTEM_BUILD_INFOS_FILE);
+            File buildInfoPlugins = new File(pluginsPath, BUILD_INFOS_FILE);
+            if (!buildInfoPlugins.exists()) {
+              if (Config.LOGV) {
+                Log.v(TAG, "build.prop in plugins directory " + pluginsPath
+                  + " does not exist, therefore it's a new system image");
+              }
+              return true;
+            } else {
+              String buildInfo = contentsOfFile(buildInfoFile);
+              String buildInfoPlugin = contentsOfFile(buildInfoPlugins);
+              if (buildInfo == null || buildInfoPlugin == null
+                  || buildInfo.compareTo(buildInfoPlugin) != 0) {
+                if (Config.LOGV) {
+                  Log.v(TAG, "build.prop are different, "
+                    + " therefore it's a new system image");
+                }
+                return true;
+              }
+            }
+          } catch (Exception e) {
+            Log.e(TAG, "Exc in newSystemImage(): " + e);
+          }
+          return false;
+        }
+
+        /**
+         * Check if the version of the plugins contained in the
+         * Browser assets is the same as the version of the plugins
+         * in the plugins directory.
+         * We simply iterate on every file in the assets/plugins
+         * and return false if a file listed in the assets does
+         * not exist in the plugins directory.
+         */
+        private boolean checkIsDifferentVersions() {
+          try {
+            ZipFile zip = new ZipFile(APK_PATH);
+            Vector<ZipEntry> files = pluginsFilesFromZip(zip);
+            int zipFilterLength = ZIP_FILTER.length();
+
+            Enumeration entries = files.elements();
+            while (entries.hasMoreElements()) {
+              ZipEntry entry = (ZipEntry) entries.nextElement();
+              String path = entry.getName().substring(zipFilterLength);
+              File outputFile = new File(pluginsPath, path);
+              if (!outputFile.exists()) {
+                if (Config.LOGV) {
+                  Log.v(TAG, "checkIsDifferentVersions(): extracted file "
+                    + path + " does not exist, we have a different version");
+                }
+                return true;
+              }
+            }
+          } catch (IOException e) {
+            Log.e(TAG, "Exception in checkDifferentVersions(): " + e);
+          }
+          return false;
+        }
+
+        /**
+         * Copy every files from the assets/plugins directory
+         * to the app_plugins directory in the data partition.
+         * Once copied, we copy over the SYSTEM_BUILD_INFOS file
+         * in the plugins directory.
+         *
+         * NOTE: we directly access the content from the Browser
+         * package (it's a zip file) and do not use AssetManager
+         * as there is a limit of 1Mb (see Asset.h)
+         */
+        public void run() {
+            // Lower the priority
+            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
+            try {
+                if (pluginsPath == null) {
+                    Log.e(TAG, "No plugins path found!");
+                    return;
+                }
+
+                ZipFile zip = new ZipFile(APK_PATH);
+                Vector<ZipEntry> files = pluginsFilesFromZip(zip);
+                Vector<File> plugins = new Vector<File>();
+                int zipFilterLength = ZIP_FILTER.length();
+
+                Enumeration entries = files.elements();
+                while (entries.hasMoreElements()) {
+                    ZipEntry entry = (ZipEntry) entries.nextElement();
+                    String path = entry.getName().substring(zipFilterLength);
+                    File outputFile = new File(pluginsPath, path);
+                    outputFile.getParentFile().mkdirs();
+
+                    if (outputFile.exists() && !mDoOverwrite) {
+                        if (Config.LOGV) {
+                            Log.v(TAG, path + " already extracted.");
+                        }
+                    } else {
+                        if (path.endsWith(PLUGIN_EXTENSION)) {
+                            // We rename plugins to be sure a half-copied
+                            // plugin is not loaded by the browser.
+                            plugins.add(outputFile);
+                            outputFile = new File(pluginsPath,
+                                path + TEMPORARY_EXTENSION);
+                        }
+                        FileOutputStream fos = new FileOutputStream(outputFile);
+                        if (Config.LOGV) {
+                            Log.v(TAG, "copy " + entry + " to "
+                                + pluginsPath + "/" + path);
+                        }
+                        copyStreams(zip.getInputStream(entry), fos);
+                    }
+                }
+
+                // We now rename the .so we copied, once all their resources
+                // are safely copied over to the user data partition.
+                Enumeration elems = plugins.elements();
+                while (elems.hasMoreElements()) {
+                    File renamedFile = (File) elems.nextElement();
+                    File sourceFile = new File(renamedFile.getPath()
+                        + TEMPORARY_EXTENSION);
+                    if (Config.LOGV) {
+                        Log.v(TAG, "rename " + sourceFile.getPath()
+                            + " to " + renamedFile.getPath());
+                    }
+                    sourceFile.renameTo(renamedFile);
+                }
+
+                copyBuildInfos();
+
+                // Refresh the plugin list.
+                if (mTabControl.getCurrentWebView() != null) {
+                    mTabControl.getCurrentWebView().refreshPlugins(false);
+                }
+            } catch (IOException e) {
+                Log.e(TAG, "IO Exception: " + e);
+            }
+        }
+    };
+
+    /**
+     * Copy the content of assets/plugins/ to the app_plugins directory
+     * in the data partition.
+     *
+     * This function is called every time the browser is started.
+     * We first check if the system image is newer than the one that
+     * copied the plugins (if there's plugins in the data partition).
+     * If this is the case, we then check if the versions are different.
+     * If they are different, we clean the plugins directory in the
+     * data partition, then start a thread to copy the plugins while
+     * the browser continue to load.
+     *
+     * @param overwrite if true overwrite the files even if they are
+     * already present (to let the user "reset" the plugins if needed).
+     */
+    private void copyPlugins(boolean overwrite) {
+        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
+        copyPluginsFromAssets.initPluginsPath();
+        if (copyPluginsFromAssets.newSystemImage())  {
+          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
+            copyPluginsFromAssets.cleanPluginsDirectory();
+            Thread copyplugins = new Thread(copyPluginsFromAssets);
+            copyplugins.setName("CopyPlugins");
+            copyplugins.start();
+          }
+        }
+    }
+
+    private class ClearThumbnails extends AsyncTask<File, Void, Void> {
+        @Override
+        public Void doInBackground(File... files) {
+            if (files != null) {
+                for (File f : files) {
+                    f.delete();
+                }
+            }
+            return null;
+        }
+    }
+
+    @Override public void onCreate(Bundle icicle) {
+        if (Config.LOGV) {
+            Log.v(LOGTAG, this + " onStart");
+        }
+        super.onCreate(icicle);
+        this.requestWindowFeature(Window.FEATURE_LEFT_ICON);
+        this.requestWindowFeature(Window.FEATURE_RIGHT_ICON);
+        this.requestWindowFeature(Window.FEATURE_PROGRESS);
+        this.requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
+
+        // test the browser in OpenGL
+        // requestWindowFeature(Window.FEATURE_OPENGL);
+
+        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
+
+        mResolver = getContentResolver();
+
+        setBaseSearchUrl(PreferenceManager.getDefaultSharedPreferences(this)
+                .getString("search_url", ""));
+
+        //
+        // start MASF proxy service
+        //
+        //Intent proxyServiceIntent = new Intent();
+        //proxyServiceIntent.setComponent
+        //    (new ComponentName(
+        //        "com.android.masfproxyservice",
+        //        "com.android.masfproxyservice.MasfProxyService"));
+        //startService(proxyServiceIntent, null);
+
+        mSecLockIcon = Resources.getSystem().getDrawable(
+                android.R.drawable.ic_secure);
+        mMixLockIcon = Resources.getSystem().getDrawable(
+                android.R.drawable.ic_partial_secure);
+        mGenericFavicon = getResources().getDrawable(
+                R.drawable.app_web_browser_sm);
+
+        mContentView = (FrameLayout) getWindow().getDecorView().findViewById(
+                com.android.internal.R.id.content);
+
+        // Create the tab control and our initial tab
+        mTabControl = new TabControl(this);
+
+        // Open the icon database and retain all the bookmark urls for favicons
+        retainIconsOnStartup();
+
+        // Keep a settings instance handy.
+        mSettings = BrowserSettings.getInstance();
+        mSettings.setTabControl(mTabControl);
+        mSettings.loadFromDb(this);
+
+        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
+        mWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "Browser");
+
+        if (!mTabControl.restoreState(icicle)) {
+            // clear up the thumbnail directory if we can't restore the state as
+            // none of the files in the directory are referenced any more.
+            new ClearThumbnails().execute(
+                    mTabControl.getThumbnailDir().listFiles());
+            final Intent intent = getIntent();
+            final Bundle extra = intent.getExtras();
+            // Create an initial tab.
+            // If the intent is ACTION_VIEW and data is not null, the Browser is
+            // invoked to view the content by another application. In this case,
+            // the tab will be close when exit.
+            final TabControl.Tab t = mTabControl.createNewTab(
+                    Intent.ACTION_VIEW.equals(intent.getAction()) &&
+                    intent.getData() != null);
+            mTabControl.setCurrentTab(t);
+            // This is one of the only places we call attachTabToContentView
+            // without animating from the tab picker.
+            attachTabToContentView(t);
+            WebView webView = t.getWebView();
+            if (extra != null) {
+                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
+                if (scale > 0 && scale <= 1000) {
+                    webView.setInitialScale(scale);
+                }
+            }
+            // If we are not restoring from an icicle, then there is a high
+            // likely hood this is the first run. So, check to see if the
+            // homepage needs to be configured and copy any plugins from our
+            // asset directory to the data partition.
+            if ((extra == null || !extra.getBoolean("testing"))
+                    && !mSettings.isLoginInitialized()) {
+                setupHomePage();
+            }
+            copyPlugins(true);
+
+            String url = getUrlFromIntent(intent);
+            if (url == null || url.length() == 0) {
+                if (mSettings.isLoginInitialized()) {
+                    webView.loadUrl(mSettings.getHomePage());
+                } else {
+                    waitForCredentials();
+                }
+            } else {
+                webView.loadUrl(url);
+            }
+        } else {
+            // TabControl.restoreState() will create a new tab even if
+            // restoring the state fails. Attach it to the view here since we
+            // are not animating from the tab picker.
+            attachTabToContentView(mTabControl.getCurrentTab());
+        }
+
+        /* enables registration for changes in network status from
+           http stack */
+        mNetworkStateChangedFilter = new IntentFilter();
+        mNetworkStateChangedFilter.addAction(
+                ConnectivityManager.CONNECTIVITY_ACTION);
+        mNetworkStateIntentReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (intent.getAction().equals(
+                            ConnectivityManager.CONNECTIVITY_ACTION)) {
+                        boolean down = intent.getBooleanExtra(
+                                ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
+                        onNetworkToggle(!down);
+                    }
+                }
+            };
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        TabControl.Tab current = mTabControl.getCurrentTab();
+        // When a tab is closed on exit, the current tab index is set to -1.
+        // Reset before proceed as Browser requires the current tab to be set.
+        if (current == null) {
+            // Try to reset the tab in case the index was incorrect.
+            current = mTabControl.getTab(0);
+            if (current == null) {
+                // No tabs at all so just ignore this intent.
+                return;
+            }
+            mTabControl.setCurrentTab(current);
+            attachTabToContentView(current);
+            resetTitleAndIcon(current.getWebView());
+        }
+        final String action = intent.getAction();
+        final int flags = intent.getFlags();
+        if (Intent.ACTION_MAIN.equals(action) ||
+                (flags & Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY) != 0) {
+            // just resume the browser
+            return;
+        }
+        if (Intent.ACTION_VIEW.equals(action)
+                || Intent.ACTION_SEARCH.equals(action)
+                || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
+                || Intent.ACTION_WEB_SEARCH.equals(action)) {
+            String url = getUrlFromIntent(intent);
+            if (url == null || url.length() == 0) {
+                url = mSettings.getHomePage();
+            }
+            if (Intent.ACTION_VIEW.equals(action) &&
+                    (flags & Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT) != 0) {
+                // if FLAG_ACTIVITY_BROUGHT_TO_FRONT flag is on, the url will be
+                // opened in a new tab unless we have reached MAX_TABS. Then the
+                // url will be opened in the current tab. If a new tab is
+                // created, it will have "true" for exit on close.
+                openTabAndShow(url, null, true);
+            } else {
+                if ("about:debug".equals(url)) {
+                    mSettings.toggleDebugSettings();
+                    return;
+                }
+                // If the Window overview is up and we are not in the midst of
+                // an animation, animate away from the Window overview.
+                if (mTabOverview != null && mAnimationCount == 0) {
+                    sendAnimateFromOverview(current, false, url,
+                            TAB_OVERVIEW_DELAY, null);
+                } else {
+                    // Get rid of the subwindow if it exists
+                    dismissSubWindow(current);
+                    current.getWebView().loadUrl(url);
+                }
+            }
+        }
+    }
+
+    private String getUrlFromIntent(Intent intent) {
+        String url = null;
+        if (intent != null) {
+            final String action = intent.getAction();
+            if (Intent.ACTION_VIEW.equals(action)) {
+                url = smartUrlFilter(intent.getData());
+                if (url != null && url.startsWith("content:")) {
+                    /* Append mimetype so webview knows how to display */
+                    String mimeType = intent.resolveType(getContentResolver());
+                    if (mimeType != null) {
+                        url += "?" + mimeType;
+                    }
+                }
+            } else if (Intent.ACTION_SEARCH.equals(action)
+                    || MediaStore.INTENT_ACTION_MEDIA_SEARCH.equals(action)
+                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
+                url = intent.getStringExtra(SearchManager.QUERY);
+                if (url != null) {
+                    mLastEnteredUrl = url;
+                    // Don't add Urls, just search terms.
+                    // Urls will get added when the page is loaded.
+                    if (!Regex.WEB_URL_PATTERN.matcher(url).matches()) {
+                        Browser.updateVisitedHistory(mResolver, url, false);
+                    }
+                    // In general, we shouldn't modify URL from Intent.
+                    // But currently, we get the user-typed URL from search box as well.
+                    url = fixUrl(url);
+                    url = smartUrlFilter(url);
+                    String searchSource = "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&";
+                    if (url.contains(searchSource)) {
+                        String source = null;
+                        final Bundle appData = intent.getBundleExtra(SearchManager.APP_DATA);
+                        if (appData != null) {
+                            source = appData.getString(SearchManager.SOURCE);
+                        }
+                        if (TextUtils.isEmpty(source)) {
+                            source = GOOGLE_SEARCH_SOURCE_UNKNOWN;
+                        }
+                        url = url.replace(searchSource, "&source=android-"+source+"&");
+                    }
+                }
+            }
+        }
+        return url;
+    }
+
+    /* package */ static String fixUrl(String inUrl) {
+        if (inUrl.startsWith("http://") || inUrl.startsWith("https://"))
+            return inUrl;
+        if (inUrl.startsWith("http:") ||
+                inUrl.startsWith("https:")) {
+            if (inUrl.startsWith("http:/") || inUrl.startsWith("https:/")) {
+                inUrl = inUrl.replaceFirst("/", "//");
+            } else inUrl = inUrl.replaceFirst(":", "://");
+        }
+        return inUrl;
+    }
+
+    /**
+     * Looking for the pattern like this
+     *
+     *          *
+     *         * *
+     *      ***   *     *******
+     *             *   *
+     *              * *
+     *               *
+     */
+    private final SensorListener mSensorListener = new SensorListener() {
+        private long mLastGestureTime;
+        private float[] mPrev = new float[3];
+        private float[] mPrevDiff = new float[3];
+        private float[] mDiff = new float[3];
+        private float[] mRevertDiff = new float[3];
+
+        public void onSensorChanged(int sensor, float[] values) {
+            boolean show = false;
+            float[] diff = new float[3];
+
+            for (int i = 0; i < 3; i++) {
+                diff[i] = values[i] - mPrev[i];
+                if (Math.abs(diff[i]) > 1) {
+                    show = true;
+                }
+                if ((diff[i] > 1.0 && mDiff[i] < 0.2)
+                        || (diff[i] < -1.0 && mDiff[i] > -0.2)) {
+                    // start track when there is a big move, or revert
+                    mRevertDiff[i] = mDiff[i];
+                    mDiff[i] = 0;
+                } else if (diff[i] > -0.2 && diff[i] < 0.2) {
+                    // reset when it is flat
+                    mDiff[i] = mRevertDiff[i]  = 0;
+                }
+                mDiff[i] += diff[i];
+                mPrevDiff[i] = diff[i];
+                mPrev[i] = values[i];
+            }
+
+            if (false) {
+                // only shows if we think the delta is big enough, in an attempt
+                // to detect "serious" moves left/right or up/down
+                Log.d("BrowserSensorHack", "sensorChanged " + sensor + " ("
+                        + values[0] + ", " + values[1] + ", " + values[2] + ")"
+                        + " diff(" + diff[0] + " " + diff[1] + " " + diff[2]
+                        + ")");
+                Log.d("BrowserSensorHack", "      mDiff(" + mDiff[0] + " "
+                        + mDiff[1] + " " + mDiff[2] + ")" + " mRevertDiff("
+                        + mRevertDiff[0] + " " + mRevertDiff[1] + " "
+                        + mRevertDiff[2] + ")");
+            }
+
+            long now = android.os.SystemClock.uptimeMillis();
+            if (now - mLastGestureTime > 1000) {
+                mLastGestureTime = 0;
+
+                float y = mDiff[1];
+                float z = mDiff[2];
+                float ay = Math.abs(y);
+                float az = Math.abs(z);
+                float ry = mRevertDiff[1];
+                float rz = mRevertDiff[2];
+                float ary = Math.abs(ry);
+                float arz = Math.abs(rz);
+                boolean gestY = ay > 2.5f && ary > 1.0f && ay > ary;
+                boolean gestZ = az > 3.5f && arz > 1.0f && az > arz;
+
+                if ((gestY || gestZ) && !(gestY && gestZ)) {
+                    WebView view = mTabControl.getCurrentWebView();
+
+                    if (view != null) {
+                        if (gestZ) {
+                            if (z < 0) {
+                                view.zoomOut();
+                            } else {
+                                view.zoomIn();
+                            }
+                        } else {
+                            view.flingScroll(0, Math.round(y * 100));
+                        }
+                    }
+                    mLastGestureTime = now;
+                }
+            }
+        }
+
+        public void onAccuracyChanged(int sensor, int accuracy) {
+            // TODO Auto-generated method stub
+
+        }
+    };
+
+    @Override protected void onResume() {
+        super.onResume();
+        if (Config.LOGV) {
+            Log.v(LOGTAG, "BrowserActivity.onResume: this=" + this);
+        }
+
+        if (!mActivityInPause) {
+            Log.e(LOGTAG, "BrowserActivity is already resumed.");
+            return;
+        }
+
+        mActivityInPause = false;
+        resumeWebView();
+
+        if (mWakeLock.isHeld()) {
+            mHandler.removeMessages(RELEASE_WAKELOCK);
+            mWakeLock.release();
+        }
+
+        if (mCredsDlg != null) {
+            if (!mHandler.hasMessages(CANCEL_CREDS_REQUEST)) {
+             // In case credential request never comes back
+                mHandler.sendEmptyMessageDelayed(CANCEL_CREDS_REQUEST, 6000);
+            }
+        }
+
+        registerReceiver(mNetworkStateIntentReceiver,
+                         mNetworkStateChangedFilter);
+        WebView.enablePlatformNotifications();
+
+        if (mSettings.doFlick()) {
+            if (mSensorManager == null) {
+                mSensorManager = (SensorManager) getSystemService(
+                        Context.SENSOR_SERVICE);
+            }
+            mSensorManager.registerListener(mSensorListener,
+                    SensorManager.SENSOR_ACCELEROMETER,
+                    SensorManager.SENSOR_DELAY_FASTEST);
+        } else {
+            mSensorManager = null;
+        }
+    }
+
+    /**
+     *  onSaveInstanceState(Bundle map)
+     *  onSaveInstanceState is called right before onStop(). The map contains
+     *  the saved state.
+     */
+    @Override protected void onSaveInstanceState(Bundle outState) {
+        if (Config.LOGV) {
+            Log.v(LOGTAG, "BrowserActivity.onSaveInstanceState: this=" + this);
+        }
+        // the default implementation requires each view to have an id. As the
+        // browser handles the state itself and it doesn't use id for the views,
+        // don't call the default implementation. Otherwise it will trigger the
+        // warning like this, "couldn't save which view has focus because the
+        // focused view XXX has no id".
+
+        // Save all the tabs
+        mTabControl.saveState(outState);
+    }
+
+    @Override protected void onPause() {
+        super.onPause();
+
+        if (mActivityInPause) {
+            Log.e(LOGTAG, "BrowserActivity is already paused.");
+            return;
+        }
+
+        mActivityInPause = true;
+        if (mTabControl.getCurrentIndex() >= 0 && !pauseWebView()) {
+            mWakeLock.acquire();
+            mHandler.sendMessageDelayed(mHandler
+                    .obtainMessage(RELEASE_WAKELOCK), WAKELOCK_TIMEOUT);
+        }
+
+        // Clear the credentials toast if it is up
+        if (mCredsDlg != null && mCredsDlg.isShowing()) {
+            mCredsDlg.dismiss();
+        }
+        mCredsDlg = null;
+
+        cancelStopToast();
+
+        // unregister network state listener
+        unregisterReceiver(mNetworkStateIntentReceiver);
+        WebView.disablePlatformNotifications();
+
+        if (mSensorManager != null) {
+            mSensorManager.unregisterListener(mSensorListener);
+        }
+    }
+
+    @Override protected void onDestroy() {
+        if (Config.LOGV) {
+            Log.v(LOGTAG, "BrowserActivity.onDestroy: this=" + this);
+        }
+        super.onDestroy();
+        // Remove the current tab and sub window
+        TabControl.Tab t = mTabControl.getCurrentTab();
+        dismissSubWindow(t);
+        removeTabFromContentView(t);
+        // Destroy all the tabs
+        mTabControl.destroy();
+        WebIconDatabase.getInstance().close();
+        if (mGlsConnection != null) {
+            unbindService(mGlsConnection);
+            mGlsConnection = null;
+        }
+
+        //
+        // stop MASF proxy service
+        //
+        //Intent proxyServiceIntent = new Intent();
+        //proxyServiceIntent.setComponent
+        //   (new ComponentName(
+        //        "com.android.masfproxyservice",
+        //        "com.android.masfproxyservice.MasfProxyService"));
+        //stopService(proxyServiceIntent);
+    }
+
+    @Override
+    public void onConfigurationChanged(Configuration newConfig) {
+        super.onConfigurationChanged(newConfig);
+
+        if (mPageInfoDialog != null) {
+            mPageInfoDialog.dismiss();
+            showPageInfo(
+                mPageInfoView,
+                mPageInfoFromShowSSLCertificateOnError.booleanValue());
+        }
+        if (mSSLCertificateDialog != null) {
+            mSSLCertificateDialog.dismiss();
+            showSSLCertificate(
+                mSSLCertificateView);
+        }
+        if (mSSLCertificateOnErrorDialog != null) {
+            mSSLCertificateOnErrorDialog.dismiss();
+            showSSLCertificateOnError(
+                mSSLCertificateOnErrorView,
+                mSSLCertificateOnErrorHandler,
+                mSSLCertificateOnErrorError);
+        }
+        if (mHttpAuthenticationDialog != null) {
+            String title = ((TextView) mHttpAuthenticationDialog
+                    .findViewById(com.android.internal.R.id.alertTitle)).getText()
+                    .toString();
+            String name = ((TextView) mHttpAuthenticationDialog
+                    .findViewById(R.id.username_edit)).getText().toString();
+            String password = ((TextView) mHttpAuthenticationDialog
+                    .findViewById(R.id.password_edit)).getText().toString();
+            int focusId = mHttpAuthenticationDialog.getCurrentFocus()
+                    .getId();
+            mHttpAuthenticationDialog.dismiss();
+            showHttpAuthentication(mHttpAuthHandler, null, null, title,
+                    name, password, focusId);
+        }
+        if (mFindDialog != null && mFindDialog.isShowing()) {
+            mFindDialog.onConfigurationChanged(newConfig);
+        }
+    }
+
+    @Override public void onLowMemory() {
+        super.onLowMemory();
+        mTabControl.freeMemory();
+    }
+
+    private boolean resumeWebView() {
+        if ((!mActivityInPause && !mPageStarted) ||
+                (mActivityInPause && mPageStarted)) {
+            CookieSyncManager.getInstance().startSync();
+            WebView w = mTabControl.getCurrentWebView();
+            if (w != null) {
+                w.resumeTimers();
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean pauseWebView() {
+        if (mActivityInPause && !mPageStarted) {
+            CookieSyncManager.getInstance().stopSync();
+            WebView w = mTabControl.getCurrentWebView();
+            if (w != null) {
+                w.pauseTimers();
+            }
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    /*
+     * This function is called when we are launching for the first time. We
+     * are waiting for the login credentials before loading Google home
+     * pages. This way the user will be logged in straight away.
+     */
+    private void waitForCredentials() {
+        // Show a toast
+        mCredsDlg = new ProgressDialog(this);
+        mCredsDlg.setIndeterminate(true);
+        mCredsDlg.setMessage(getText(R.string.retrieving_creds_dlg_msg));
+        // If the user cancels the operation, then cancel the Google
+        // Credentials request.
+        mCredsDlg.setCancelMessage(mHandler.obtainMessage(CANCEL_CREDS_REQUEST));
+        mCredsDlg.show();
+
+        // We set a timeout for the retrieval of credentials in onResume()
+        // as that is when we have freed up some CPU time to get
+        // the login credentials.
+    }
+
+    /*
+     * If we have received the credentials or we have timed out and we are
+     * showing the credentials dialog, then it is time to move on.
+     */
+    private void resumeAfterCredentials() {
+        if (mCredsDlg == null) {
+            return;
+        }
+
+        // Clear the toast
+        if (mCredsDlg.isShowing()) {
+            mCredsDlg.dismiss();
+        }
+        mCredsDlg = null;
+
+        // Clear any pending timeout
+        mHandler.removeMessages(CANCEL_CREDS_REQUEST);
+
+        // Load the page
+        WebView w = mTabControl.getCurrentWebView();
+        if (w != null) {
+            w.loadUrl(mSettings.getHomePage());
+        }
+
+        // Update the settings, need to do this last as it can take a moment
+        // to persist the settings. In the mean time we could be loading
+        // content.
+        mSettings.setLoginInitialized(this);
+    }
+
+    // Open the icon database and retain all the icons for visited sites.
+    private void retainIconsOnStartup() {
+        final WebIconDatabase db = WebIconDatabase.getInstance();
+        db.open(getDir("icons", 0).getPath());
+        try {
+            Cursor c = Browser.getAllBookmarks(mResolver);
+            if (!c.moveToFirst()) {
+                c.deactivate();
+                return;
+            }
+            int urlIndex = c.getColumnIndex(Browser.BookmarkColumns.URL);
+            do {
+                String url = c.getString(urlIndex);
+                db.retainIconForPageUrl(url);
+            } while (c.moveToNext());
+            c.deactivate();
+        } catch (IllegalStateException e) {
+            Log.e(LOGTAG, "retainIconsOnStartup", e);
+        }
+    }
+
+    // Helper method for getting the top window.
+    WebView getTopWindow() {
+        return mTabControl.getCurrentTopWebView();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.browser, menu);
+        mMenu = menu;
+        updateInLoadMenuItems();
+        return true;
+    }
+
+    /**
+     * As the menu can be open when loading state changes
+     * we must manually update the state of the stop/reload menu
+     * item
+     */
+    private void updateInLoadMenuItems() {
+        if (mMenu == null) {
+            return;
+        }
+        MenuItem src = mInLoad ?
+                mMenu.findItem(R.id.stop_menu_id):
+                    mMenu.findItem(R.id.reload_menu_id);
+        MenuItem dest = mMenu.findItem(R.id.stop_reload_menu_id);
+        dest.setIcon(src.getIcon());
+        dest.setTitle(src.getTitle());
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        // chording is not an issue with context menus, but we use the same
+        // options selector, so set mCanChord to true so we can access them.
+        mCanChord = true;
+        int id = item.getItemId();
+        final WebView webView = getTopWindow();
+        final HashMap hrefMap = new HashMap();
+        hrefMap.put("webview", webView);
+        final Message msg = mHandler.obtainMessage(
+                FOCUS_NODE_HREF, id, 0, hrefMap);
+        switch (id) {
+            // -- Browser context menu
+            case R.id.open_context_menu_id:
+            case R.id.open_newtab_context_menu_id:
+            case R.id.bookmark_context_menu_id:
+            case R.id.save_link_context_menu_id:
+            case R.id.share_link_context_menu_id:
+            case R.id.copy_link_context_menu_id:
+                webView.requestFocusNodeHref(msg);
+                break;
+
+            default:
+                // For other context menus
+                return onOptionsItemSelected(item);
+        }
+        mCanChord = false;
+        return true;
+    }
+
+    private Bundle createGoogleSearchSourceBundle(String source) {
+        Bundle bundle = new Bundle();
+        bundle.putString(SearchManager.SOURCE, source);
+        return bundle;
+    }
+
+    /**
+     * Overriding this forces the search key to launch global search.  The difference
+     * is the final "true" which requests global search.
+     */
+    @Override
+    public boolean onSearchRequested() {
+        startSearch(null, false,
+                createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_SEARCHKEY), true);
+        return true;
+    }
+
+    @Override
+    public void startSearch(String initialQuery, boolean selectInitialQuery,
+            Bundle appSearchData, boolean globalSearch) {
+        if (appSearchData == null) {
+            appSearchData = createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_TYPE);
+        }
+        super.startSearch(initialQuery, selectInitialQuery, appSearchData, globalSearch);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        if (!mCanChord) {
+            // The user has already fired a shortcut with this hold down of the
+            // menu key.
+            return false;
+        }
+        switch (item.getItemId()) {
+            // -- Main menu
+            case R.id.goto_menu_id: {
+                String url = getTopWindow().getUrl();
+                startSearch(mSettings.getHomePage().equals(url) ? null : url, true,
+                        createGoogleSearchSourceBundle(GOOGLE_SEARCH_SOURCE_GOTO), false);
+                }
+                break;
+
+            case R.id.bookmarks_menu_id:
+                bookmarksOrHistoryPicker(false);
+                break;
+
+            case R.id.windows_menu_id:
+                if (mTabControl.getTabCount() == 1) {
+                    openTabAndShow(mSettings.getHomePage(), null, false);
+                } else {
+                    tabPicker(true, mTabControl.getCurrentIndex(), false);
+                }
+                break;
+
+            case R.id.stop_reload_menu_id:
+                if (mInLoad) {
+                    stopLoading();
+                } else {
+                    getTopWindow().reload();
+                }
+                break;
+
+            case R.id.back_menu_id:
+                getTopWindow().goBack();
+                break;
+
+            case R.id.forward_menu_id:
+                getTopWindow().goForward();
+                break;
+
+            case R.id.close_menu_id:
+                // Close the subwindow if it exists.
+                if (mTabControl.getCurrentSubWindow() != null) {
+                    dismissSubWindow(mTabControl.getCurrentTab());
+                    break;
+                }
+                final int currentIndex = mTabControl.getCurrentIndex();
+                final TabControl.Tab parent =
+                        mTabControl.getCurrentTab().getParentTab();
+                int indexToShow = -1;
+                if (parent != null) {
+                    indexToShow = mTabControl.getTabIndex(parent);
+                } else {
+                    // Get the last tab in the list. If it is the current tab,
+                    // subtract 1 more.
+                    indexToShow = mTabControl.getTabCount() - 1;
+                    if (currentIndex == indexToShow) {
+                        indexToShow--;
+                    }
+                }
+                switchTabs(currentIndex, indexToShow, true);
+                break;
+
+            case R.id.homepage_menu_id:
+                TabControl.Tab current = mTabControl.getCurrentTab();
+                if (current != null) {
+                    dismissSubWindow(current);
+                    current.getWebView().loadUrl(mSettings.getHomePage());
+                }
+                break;
+
+            case R.id.preferences_menu_id:
+                Intent intent = new Intent(this,
+                        BrowserPreferencesPage.class);
+                startActivityForResult(intent, PREFERENCES_PAGE);
+                break;
+
+            case R.id.find_menu_id:
+                if (null == mFindDialog) {
+                    mFindDialog = new FindDialog(this);
+                }
+                mFindDialog.setWebView(getTopWindow());
+                mFindDialog.show();
+                mMenuState = EMPTY_MENU;
+                break;
+
+            case R.id.select_text_id:
+                getTopWindow().emulateShiftHeld();
+                break;
+            case R.id.page_info_menu_id:
+                showPageInfo(mTabControl.getCurrentTab(), false);
+                break;
+
+            case R.id.classic_history_menu_id:
+                bookmarksOrHistoryPicker(true);
+                break;
+
+            case R.id.share_page_menu_id:
+                Browser.sendString(this, getTopWindow().getUrl());
+                break;
+
+            case R.id.dump_nav_menu_id:
+                getTopWindow().debugDump();
+                break;
+
+            case R.id.zoom_in_menu_id:
+                getTopWindow().zoomIn();
+                break;
+
+            case R.id.zoom_out_menu_id:
+                getTopWindow().zoomOut();
+                break;
+
+            case R.id.view_downloads_menu_id:
+                viewDownloads(null);
+                break;
+
+            // -- Tab menu
+            case R.id.view_tab_menu_id:
+                if (mTabListener != null && mTabOverview != null) {
+                    int pos = mTabOverview.getContextMenuPosition(item);
+                    mTabOverview.setCurrentIndex(pos);
+                    mTabListener.onClick(pos);
+                }
+                break;
+
+            case R.id.remove_tab_menu_id:
+                if (mTabListener != null && mTabOverview != null) {
+                    int pos = mTabOverview.getContextMenuPosition(item);
+                    mTabListener.remove(pos);
+                }
+                break;
+
+            case R.id.new_tab_menu_id:
+                // No need to check for mTabOverview here since we are not
+                // dependent on it for a position.
+                if (mTabListener != null) {
+                    // If the overview happens to be non-null, make the "New
+                    // Tab" cell visible.
+                    if (mTabOverview != null) {
+                        mTabOverview.setCurrentIndex(ImageGrid.NEW_TAB);
+                    }
+                    mTabListener.onClick(ImageGrid.NEW_TAB);
+                }
+                break;
+
+            case R.id.bookmark_tab_menu_id:
+                if (mTabListener != null && mTabOverview != null) {
+                    int pos = mTabOverview.getContextMenuPosition(item);
+                    TabControl.Tab t = mTabControl.getTab(pos);
+                    // Since we called populatePickerData for all of the
+                    // tabs, getTitle and getUrl will return appropriate
+                    // values.
+                    Browser.saveBookmark(BrowserActivity.this, t.getTitle(),
+                            t.getUrl());
+                }
+                break;
+
+            case R.id.history_tab_menu_id:
+                bookmarksOrHistoryPicker(true);
+                break;
+
+            case R.id.bookmarks_tab_menu_id:
+                bookmarksOrHistoryPicker(false);
+                break;
+
+            case R.id.properties_tab_menu_id:
+                if (mTabListener != null && mTabOverview != null) {
+                    int pos = mTabOverview.getContextMenuPosition(item);
+                    showPageInfo(mTabControl.getTab(pos), false);
+                }
+                break;
+
+            case R.id.window_one_menu_id:
+            case R.id.window_two_menu_id:
+            case R.id.window_three_menu_id:
+            case R.id.window_four_menu_id:
+            case R.id.window_five_menu_id:
+            case R.id.window_six_menu_id:
+            case R.id.window_seven_menu_id:
+            case R.id.window_eight_menu_id:
+                {
+                    int menuid = item.getItemId();
+                    for (int id = 0; id < WINDOW_SHORTCUT_ID_ARRAY.length; id++) {
+                        if (WINDOW_SHORTCUT_ID_ARRAY[id] == menuid) {
+                            TabControl.Tab desiredTab = mTabControl.getTab(id);
+                            if (desiredTab != null &&
+                                    desiredTab != mTabControl.getCurrentTab()) {
+                                switchTabs(mTabControl.getCurrentIndex(), id, false);
+                            }
+                            break;
+                        }
+                    }
+                }
+                break;
+
+            default:
+                if (!super.onOptionsItemSelected(item)) {
+                    return false;
+                }
+                // Otherwise fall through.
+        }
+        mCanChord = false;
+        return true;
+    }
+
+    public void closeFind() {
+        mMenuState = R.id.MAIN_MENU;
+    }
+
+    @Override public boolean onPrepareOptionsMenu(Menu menu)
+    {
+        // This happens when the user begins to hold down the menu key, so
+        // allow them to chord to get a shortcut.
+        mCanChord = true;
+        // Note: setVisible will decide whether an item is visible; while
+        // setEnabled() will decide whether an item is enabled, which also means
+        // whether the matching shortcut key will function.
+        super.onPrepareOptionsMenu(menu);
+        switch (mMenuState) {
+            case R.id.TAB_MENU:
+                if (mCurrentMenuState != mMenuState) {
+                    menu.setGroupVisible(R.id.MAIN_MENU, false);
+                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
+                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
+                    menu.setGroupVisible(R.id.TAB_MENU, true);
+                    menu.setGroupEnabled(R.id.TAB_MENU, true);
+                }
+                boolean newT = mTabControl.getTabCount() < TabControl.MAX_TABS;
+                final MenuItem tab = menu.findItem(R.id.new_tab_menu_id);
+                tab.setVisible(newT);
+                tab.setEnabled(newT);
+                break;
+            case EMPTY_MENU:
+                if (mCurrentMenuState != mMenuState) {
+                    menu.setGroupVisible(R.id.MAIN_MENU, false);
+                    menu.setGroupEnabled(R.id.MAIN_MENU, false);
+                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, false);
+                    menu.setGroupVisible(R.id.TAB_MENU, false);
+                    menu.setGroupEnabled(R.id.TAB_MENU, false);
+                }
+                break;
+            default:
+                if (mCurrentMenuState != mMenuState) {
+                    menu.setGroupVisible(R.id.MAIN_MENU, true);
+                    menu.setGroupEnabled(R.id.MAIN_MENU, true);
+                    menu.setGroupEnabled(R.id.MAIN_SHORTCUT_MENU, true);
+                    menu.setGroupVisible(R.id.TAB_MENU, false);
+                    menu.setGroupEnabled(R.id.TAB_MENU, false);
+                }
+                final WebView w = getTopWindow();
+                boolean canGoBack = false;
+                boolean canGoForward = false;
+                boolean isHome = false;
+                if (w != null) {
+                    canGoBack = w.canGoBack();
+                    canGoForward = w.canGoForward();
+                    isHome = mSettings.getHomePage().equals(w.getUrl());
+                }
+                final MenuItem back = menu.findItem(R.id.back_menu_id);
+                back.setEnabled(canGoBack);
+
+                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
+                home.setEnabled(!isHome);
+
+                menu.findItem(R.id.forward_menu_id)
+                        .setEnabled(canGoForward);
+
+                // decide whether to show the share link option
+                PackageManager pm = getPackageManager();
+                Intent send = new Intent(Intent.ACTION_SEND);
+                send.setType("text/plain");
+                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
+                menu.findItem(R.id.share_page_menu_id).setVisible(ri != null);
+
+                // If there is only 1 window, the text will be "New window"
+                final MenuItem windows = menu.findItem(R.id.windows_menu_id);
+                windows.setTitleCondensed(mTabControl.getTabCount() > 1 ?
+                        getString(R.string.view_tabs_condensed) :
+                        getString(R.string.tab_picker_new_tab));
+
+                boolean isNavDump = mSettings.isNavDump();
+                final MenuItem nav = menu.findItem(R.id.dump_nav_menu_id);
+                nav.setVisible(isNavDump);
+                nav.setEnabled(isNavDump);
+                break;
+        }
+        mCurrentMenuState = mMenuState;
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        WebView webview = (WebView) v;
+        WebView.HitTestResult result = webview.getHitTestResult();
+        if (result == null) {
+            return;
+        }
+
+        int type = result.getType();
+        if (type == WebView.HitTestResult.UNKNOWN_TYPE) {
+            Log.w(LOGTAG,
+                    "We should not show context menu when nothing is touched");
+            return;
+        }
+        if (type == WebView.HitTestResult.EDIT_TEXT_TYPE) {
+            // let TextView handles context menu
+            return;
+        }
+
+        // Note, http://b/issue?id=1106666 is requesting that
+        // an inflated menu can be used again. This is not available
+        // yet, so inflate each time (yuk!)
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.browsercontext, menu);
+
+        // Show the correct menu group
+        String extra = result.getExtra();
+        menu.setGroupVisible(R.id.PHONE_MENU,
+                type == WebView.HitTestResult.PHONE_TYPE);
+        menu.setGroupVisible(R.id.EMAIL_MENU,
+                type == WebView.HitTestResult.EMAIL_TYPE);
+        menu.setGroupVisible(R.id.GEO_MENU,
+                type == WebView.HitTestResult.GEO_TYPE);
+        menu.setGroupVisible(R.id.IMAGE_MENU,
+                type == WebView.HitTestResult.IMAGE_TYPE
+                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
+        menu.setGroupVisible(R.id.ANCHOR_MENU,
+                type == WebView.HitTestResult.SRC_ANCHOR_TYPE
+                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
+
+        // Setup custom handling depending on the type
+        switch (type) {
+            case WebView.HitTestResult.PHONE_TYPE:
+                menu.setHeaderTitle(Uri.decode(extra));
+                menu.findItem(R.id.dial_context_menu_id).setIntent(
+                        new Intent(Intent.ACTION_VIEW, Uri
+                                .parse(WebView.SCHEME_TEL + extra)));
+                Intent addIntent = new Intent(Intent.ACTION_INSERT_OR_EDIT);
+                addIntent.putExtra(Insert.PHONE, Uri.decode(extra));
+                addIntent.setType(Contacts.People.CONTENT_ITEM_TYPE);
+                menu.findItem(R.id.add_contact_context_menu_id).setIntent(
+                        addIntent);
+                menu.findItem(R.id.copy_phone_context_menu_id).setOnMenuItemClickListener(
+                        new Copy(extra));
+                break;
+
+            case WebView.HitTestResult.EMAIL_TYPE:
+                menu.setHeaderTitle(extra);
+                menu.findItem(R.id.email_context_menu_id).setIntent(
+                        new Intent(Intent.ACTION_VIEW, Uri
+                                .parse(WebView.SCHEME_MAILTO + extra)));
+                menu.findItem(R.id.copy_mail_context_menu_id).setOnMenuItemClickListener(
+                        new Copy(extra));
+                break;
+
+            case WebView.HitTestResult.GEO_TYPE:
+                menu.setHeaderTitle(extra);
+                menu.findItem(R.id.map_context_menu_id).setIntent(
+                        new Intent(Intent.ACTION_VIEW, Uri
+                                .parse(WebView.SCHEME_GEO
+                                        + URLEncoder.encode(extra))));
+                menu.findItem(R.id.copy_geo_context_menu_id).setOnMenuItemClickListener(
+                        new Copy(extra));
+                break;
+
+            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
+            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
+                TextView titleView = (TextView) LayoutInflater.from(this)
+                        .inflate(android.R.layout.browser_link_context_header,
+                        null);
+                titleView.setText(extra);
+                menu.setHeaderView(titleView);
+                // decide whether to show the open link in new tab option
+                menu.findItem(R.id.open_newtab_context_menu_id).setVisible(
+                        mTabControl.getTabCount() < TabControl.MAX_TABS);
+                PackageManager pm = getPackageManager();
+                Intent send = new Intent(Intent.ACTION_SEND);
+                send.setType("text/plain");
+                ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
+                menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
+                if (type == WebView.HitTestResult.SRC_ANCHOR_TYPE) {
+                    break;
+                }
+                // otherwise fall through to handle image part
+            case WebView.HitTestResult.IMAGE_TYPE:
+                if (type == WebView.HitTestResult.IMAGE_TYPE) {
+                    menu.setHeaderTitle(extra);
+                }
+                menu.findItem(R.id.view_image_context_menu_id).setIntent(
+                        new Intent(Intent.ACTION_VIEW, Uri.parse(extra)));
+                menu.findItem(R.id.download_context_menu_id).
+                        setOnMenuItemClickListener(new Download(extra));
+                break;
+
+            default:
+                Log.w(LOGTAG, "We should not get here.");
+                break;
+        }
+    }
+
+    // Used by attachTabToContentView for the WebView's ZoomControl widget.
+    private static final FrameLayout.LayoutParams ZOOM_PARAMS =
+            new FrameLayout.LayoutParams(
+                    ViewGroup.LayoutParams.FILL_PARENT,
+                    ViewGroup.LayoutParams.WRAP_CONTENT,
+                    Gravity.BOTTOM);
+
+    // Attach the given tab to the content view.
+    private void attachTabToContentView(TabControl.Tab t) {
+        final WebView main = t.getWebView();
+        // Attach the main WebView.
+        mContentView.addView(main, COVER_SCREEN_PARAMS);
+        // Attach the Zoom control widget and hide it.
+        final View zoom = main.getZoomControls();
+        mContentView.addView(zoom, ZOOM_PARAMS);
+        zoom.setVisibility(View.GONE);
+        // Attach the sub window if necessary
+        attachSubWindow(t);
+        // Request focus on the top window.
+        t.getTopWindow().requestFocus();
+    }
+
+    // Attach a sub window to the main WebView of the given tab.
+    private void attachSubWindow(TabControl.Tab t) {
+        // If a sub window exists, attach it to the content view.
+        final WebView subView = t.getSubWebView();
+        if (subView != null) {
+            final View container = t.getSubWebViewContainer();
+            mContentView.addView(container, COVER_SCREEN_PARAMS);
+            subView.requestFocus();
+        }
+    }
+
+    // Remove the given tab from the content view.
+    private void removeTabFromContentView(TabControl.Tab t) {
+        // Remove the Zoom widget and the main WebView.
+        mContentView.removeView(t.getWebView().getZoomControls());
+        mContentView.removeView(t.getWebView());
+        // Remove the sub window if it exists.
+        if (t.getSubWebView() != null) {
+            mContentView.removeView(t.getSubWebViewContainer());
+        }
+    }
+
+    // Remove the sub window if it exists. Also called by TabControl when the
+    // user clicks the 'X' to dismiss a sub window.
+    /* package */ void dismissSubWindow(TabControl.Tab t) {
+        final WebView mainView = t.getWebView();
+        if (t.getSubWebView() != null) {
+            // Remove the container view and request focus on the main WebView.
+            mContentView.removeView(t.getSubWebViewContainer());
+            mainView.requestFocus();
+            // Tell the TabControl to dismiss the subwindow. This will destroy
+            // the WebView.
+            mTabControl.dismissSubWindow(t);
+        }
+    }
+
+    // Send the ANIMTE_FROM_OVERVIEW message after changing the current tab.
+    private void sendAnimateFromOverview(final TabControl.Tab tab,
+            final boolean newTab, final String url, final int delay,
+            final Message msg) {
+        // Set the current tab.
+        mTabControl.setCurrentTab(tab);
+        // Attach the WebView so it will layout.
+        attachTabToContentView(tab);
+        // Set the view to invisibile for now.
+        tab.getWebView().setVisibility(View.INVISIBLE);
+        // If there is a sub window, make it invisible too.
+        if (tab.getSubWebView() != null) {
+            tab.getSubWebViewContainer().setVisibility(View.INVISIBLE);
+        }
+        // Create our fake animating view.
+        final AnimatingView view = new AnimatingView(this, tab);
+        // Attach it to the view system and make in invisible so it will
+        // layout but not flash white on the screen.
+        mContentView.addView(view, COVER_SCREEN_PARAMS);
+        view.setVisibility(View.INVISIBLE);
+        // Send the animate message.
+        final HashMap map = new HashMap();
+        map.put("view", view);
+        // Load the url after the AnimatingView has captured the picture. This
+        // prevents any bad layout or bad scale from being used during
+        // animation.
+        if (url != null) {
+            dismissSubWindow(tab);
+            tab.getWebView().loadUrl(url);
+        }
+        map.put("msg", msg);
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(
+                ANIMATE_FROM_OVERVIEW, newTab ? 1 : 0, 0, map), delay);
+        // Increment the count to indicate that we are in an animation.
+        mAnimationCount++;
+        // Remove the listener so we don't get any more tab changes.
+        mTabOverview.setListener(null);
+        mTabListener = null;
+        // Make the menu empty until the animation completes.
+        mMenuState = EMPTY_MENU;
+
+    }
+
+    // 500ms animation with 800ms delay
+    private static final int TAB_ANIMATION_DURATION = 500;
+    private static final int TAB_OVERVIEW_DELAY     = 800;
+
+    // Called by TabControl when a tab is requesting focus
+    /* package */ void showTab(TabControl.Tab t) {
+        // Disallow focus change during a tab animation.
+        if (mAnimationCount > 0) {
+            return;
+        }
+        int delay = 0;
+        if (mTabOverview == null) {
+            // Add a delay so the tab overview can be shown before the second
+            // animation begins.
+            delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
+            tabPicker(false, mTabControl.getTabIndex(t), false);
+        }
+        sendAnimateFromOverview(t, false, null, delay, null);
+    }
+
+    // This method does a ton of stuff. It will attempt to create a new tab
+    // if we haven't reached MAX_TABS. Otherwise it uses the current tab. If
+    // url isn't null, it will load the given url. If the tab overview is not
+    // showing, it will animate to the tab overview, create a new tab and
+    // animate away from it. After the animation completes, it will dispatch
+    // the given Message. If the tab overview is already showing (i.e. this
+    // method is called from TabListener.onClick(), the method will animate
+    // away from the tab overview.
+    private void openTabAndShow(String url, final Message msg,
+            boolean closeOnExit) {
+        final boolean newTab = mTabControl.getTabCount() != TabControl.MAX_TABS;
+        final TabControl.Tab currentTab = mTabControl.getCurrentTab();
+        if (newTab) {
+            int delay = 0;
+            // If the tab overview is up and there are animations, just load
+            // the url.
+            if (mTabOverview != null && mAnimationCount > 0) {
+                if (url != null) {
+                    // We should not have a msg here since onCreateWindow
+                    // checks the animation count and every other caller passes
+                    // null.
+                    assert msg == null;
+                    // just dismiss the subwindow and load the given url.
+                    dismissSubWindow(currentTab);
+                    currentTab.getWebView().loadUrl(url);
+                }
+            } else {
+                // show mTabOverview if it is not there.
+                if (mTabOverview == null) {
+                    // We have to delay the animation from the tab picker by the
+                    // length of the tab animation. Add a delay so the tab
+                    // overview can be shown before the second animation begins.
+                    delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
+                    tabPicker(false, ImageGrid.NEW_TAB, false);
+                }
+                // Animate from the Tab overview after any animations have
+                // finished.
+                sendAnimateFromOverview(mTabControl.createNewTab(closeOnExit),
+                        true, url, delay, msg);
+            }
+        } else if (url != null) {
+            // We should not have a msg here.
+            assert msg == null;
+            if (mTabOverview != null && mAnimationCount == 0) {
+                sendAnimateFromOverview(currentTab, false, url,
+                        TAB_OVERVIEW_DELAY, null);
+            } else {
+                // Get rid of the subwindow if it exists
+                dismissSubWindow(currentTab);
+                // Load the given url.
+                currentTab.getWebView().loadUrl(url);
+            }
+        }
+    }
+
+    private Animation createTabAnimation(final AnimatingView view,
+            final View cell, boolean scaleDown) {
+        final AnimationSet set = new AnimationSet(true);
+        final float scaleX = (float) cell.getWidth() / view.getWidth();
+        final float scaleY = (float) cell.getHeight() / view.getHeight();
+        if (scaleDown) {
+            set.addAnimation(new ScaleAnimation(1.0f, scaleX, 1.0f, scaleY));
+            set.addAnimation(new TranslateAnimation(0, cell.getLeft(), 0,
+                    cell.getTop()));
+        } else {
+            set.addAnimation(new ScaleAnimation(scaleX, 1.0f, scaleY, 1.0f));
+            set.addAnimation(new TranslateAnimation(cell.getLeft(), 0,
+                    cell.getTop(), 0));
+        }
+        set.setDuration(TAB_ANIMATION_DURATION);
+        set.setInterpolator(new DecelerateInterpolator());
+        return set;
+    }
+
+    // Animate to the tab overview. currentIndex tells us which position to
+    // animate to and newIndex is the position that should be selected after
+    // the animation completes.
+    // If remove is true, after the animation stops, a confirmation dialog will
+    // be displayed to the user.
+    private void animateToTabOverview(final int newIndex, final boolean remove,
+            final AnimatingView view) {
+        // Find the view in the ImageGrid allowing for the "New Tab" cell.
+        int position = mTabControl.getTabIndex(view.mTab);
+        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
+            position++;
+        }
+
+        // Offset the tab position with the first visible position to get a
+        // number between 0 and 3.
+        position -= mTabOverview.getFirstVisiblePosition();
+
+        // Grab the view that we are going to animate to.
+        final View v = mTabOverview.getChildAt(position);
+
+        final Animation.AnimationListener l =
+                new Animation.AnimationListener() {
+                    public void onAnimationStart(Animation a) {
+                        mTabOverview.requestFocus();
+                        // Clear the listener so we don't trigger a tab
+                        // selection.
+                        mTabOverview.setListener(null);
+                    }
+                    public void onAnimationRepeat(Animation a) {}
+                    public void onAnimationEnd(Animation a) {
+                        // We are no longer animating so decrement the count.
+                        mAnimationCount--;
+                        // Make the view GONE so that it will not draw between
+                        // now and when the Runnable is handled.
+                        view.setVisibility(View.GONE);
+                        // Post a runnable since we can't modify the view
+                        // hierarchy during this callback.
+                        mHandler.post(new Runnable() {
+                            public void run() {
+                                // Remove the AnimatingView.
+                                mContentView.removeView(view);
+                                if (mTabOverview != null) {
+                                    // Make newIndex visible.
+                                    mTabOverview.setCurrentIndex(newIndex);
+                                    // Restore the listener.
+                                    mTabOverview.setListener(mTabListener);
+                                    // Change the menu to TAB_MENU if the
+                                    // ImageGrid is interactive.
+                                    if (mTabOverview.isLive()) {
+                                        mMenuState = R.id.TAB_MENU;
+                                        mTabOverview.requestFocus();
+                                    }
+                                }
+                                // If a remove was requested, remove the tab.
+                                if (remove) {
+                                    // During a remove, the current tab has
+                                    // already changed. Remember the current one
+                                    // here.
+                                    final TabControl.Tab currentTab =
+                                            mTabControl.getCurrentTab();
+                                    // Remove the tab at newIndex from
+                                    // TabControl and the tab overview.
+                                    final TabControl.Tab tab =
+                                            mTabControl.getTab(newIndex);
+                                    mTabControl.removeTab(tab);
+                                    // Restore the current tab.
+                                    if (currentTab != tab) {
+                                        mTabControl.setCurrentTab(currentTab);
+                                    }
+                                    if (mTabOverview != null) {
+                                        mTabOverview.remove(newIndex);
+                                        // Make the current tab visible.
+                                        mTabOverview.setCurrentIndex(
+                                                mTabControl.getCurrentIndex());
+                                    }
+                                }
+                            }
+                        });
+                    }
+                };
+
+        // Do an animation if there is a view to animate to.
+        if (v != null) {
+            // Create our animation
+            final Animation anim = createTabAnimation(view, v, true);
+            anim.setAnimationListener(l);
+            // Start animating
+            view.startAnimation(anim);
+        } else {
+            // If something goes wrong and we didn't find a view to animate to,
+            // just do everything here.
+            l.onAnimationStart(null);
+            l.onAnimationEnd(null);
+        }
+    }
+
+    // Animate from the tab picker. The index supplied is the index to animate
+    // from.
+    private void animateFromTabOverview(final AnimatingView view,
+            final boolean newTab, final Message msg) {
+        // firstVisible is the first visible tab on the screen.  This helps
+        // to know which corner of the screen the selected tab is.
+        int firstVisible = mTabOverview.getFirstVisiblePosition();
+        // tabPosition is the 0-based index of of the tab being opened
+        int tabPosition = mTabControl.getTabIndex(view.mTab);
+        if (!((ImageAdapter) mTabOverview.getAdapter()).maxedOut()) {
+            // Add one to make room for the "New Tab" cell.
+            tabPosition++;
+        }
+        // If this is a new tab, animate from the "New Tab" cell.
+        if (newTab) {
+            tabPosition = 0;
+        }
+        // Location corresponds to the four corners of the screen.
+        // A new tab or 0 is upper left, 0 for an old tab is upper
+        // right, 1 is lower left, and 2 is lower right
+        int location = tabPosition - firstVisible;
+
+        // Find the view at this location.
+        final View v = mTabOverview.getChildAt(location);
+
+        // Wait until the animation completes to replace the AnimatingView.
+        final Animation.AnimationListener l =
+                new Animation.AnimationListener() {
+                    public void onAnimationStart(Animation a) {}
+                    public void onAnimationRepeat(Animation a) {}
+                    public void onAnimationEnd(Animation a) {
+                        mHandler.post(new Runnable() {
+                            public void run() {
+                                mContentView.removeView(view);
+                                // Dismiss the tab overview. If the cell at the
+                                // given location is null, set the fade
+                                // parameter to true.
+                                dismissTabOverview(v == null);
+                                TabControl.Tab t =
+                                        mTabControl.getCurrentTab();
+                                mMenuState = R.id.MAIN_MENU;
+                                // Resume regular updates.
+                                t.getWebView().resumeTimers();
+                                // Dispatch the message after the animation
+                                // completes.
+                                if (msg != null) {
+                                    msg.sendToTarget();
+                                }
+                                // The animation is done and the tab overview is
+                                // gone so allow key events and other animations
+                                // to begin.
+                                mAnimationCount--;
+                                // Reset all the title bar info.
+                                resetTitle();
+                            }
+                        });
+                    }
+                };
+
+        if (v != null) {
+            final Animation anim = createTabAnimation(view, v, false);
+            // Set the listener and start animating
+            anim.setAnimationListener(l);
+            view.startAnimation(anim);
+            // Make the view VISIBLE during the animation.
+            view.setVisibility(View.VISIBLE);
+        } else {
+            // Go ahead and do all the cleanup.
+            l.onAnimationEnd(null);
+        }
+    }
+
+    // Dismiss the tab overview applying a fade if needed.
+    private void dismissTabOverview(final boolean fade) {
+        if (fade) {
+            AlphaAnimation anim = new AlphaAnimation(1.0f, 0.0f);
+            anim.setDuration(500);
+            anim.startNow();
+            mTabOverview.startAnimation(anim);
+        }
+        // Just in case there was a problem with animating away from the tab
+        // overview
+        WebView current = mTabControl.getCurrentWebView();
+        if (current != null) {
+            current.setVisibility(View.VISIBLE);
+        } else {
+            Log.e(LOGTAG, "No current WebView in dismissTabOverview");
+        }
+        // Make the sub window container visible.
+        if (mTabControl.getCurrentSubWindow() != null) {
+            mTabControl.getCurrentTab().getSubWebViewContainer()
+                    .setVisibility(View.VISIBLE);
+        }
+        mContentView.removeView(mTabOverview);
+        mTabOverview.clear();
+        mTabOverview = null;
+        mTabListener = null;
+    }
+
+    private void openTab(String url) {
+        if (mSettings.openInBackground()) {
+            TabControl.Tab t = mTabControl.createNewTab(false);
+            if (t != null) {
+                t.getWebView().loadUrl(url);
+            }
+        } else {
+            openTabAndShow(url, null, false);
+        }
+    }
+
+    private class Copy implements OnMenuItemClickListener {
+        private CharSequence mText;
+
+        public boolean onMenuItemClick(MenuItem item) {
+            copy(mText);
+            return true;
+        }
+
+        public Copy(CharSequence toCopy) {
+            mText = toCopy;
+        }
+    }
+
+    private class Download implements OnMenuItemClickListener {
+        private String mText;
+
+        public boolean onMenuItemClick(MenuItem item) {
+            onDownloadStartNoStream(mText, null, null, null, -1);
+            return true;
+        }
+
+        public Download(String toDownload) {
+            mText = toDownload;
+        }
+    }
+
+    private void copy(CharSequence text) {
+        try {
+            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
+            if (clip != null) {
+                clip.setClipboardText(text);
+            }
+        } catch (android.os.RemoteException e) {
+            Log.e(LOGTAG, "Copy failed", e);
+        }
+    }
+
+    /**
+     * Resets the browser title-view to whatever it must be (for example, if we
+     * load a page from history).
+     */
+    private void resetTitle() {
+        resetLockIcon();
+        resetTitleIconAndProgress();
+    }
+
+    /**
+     * Resets the browser title-view to whatever it must be
+     * (for example, if we had a loading error)
+     * When we have a new page, we call resetTitle, when we
+     * have to reset the titlebar to whatever it used to be
+     * (for example, if the user chose to stop loading), we
+     * call resetTitleAndRevertLockIcon.
+     */
+    /* package */ void resetTitleAndRevertLockIcon() {
+        revertLockIcon();
+        resetTitleIconAndProgress();
+    }
+
+    /**
+     * Reset the title, favicon, and progress.
+     */
+    private void resetTitleIconAndProgress() {
+        WebView current = mTabControl.getCurrentWebView();
+        if (current == null) {
+            return;
+        }
+        resetTitleAndIcon(current);
+        int progress = current.getProgress();
+        mInLoad = (progress != 100);
+        updateInLoadMenuItems();
+        mWebChromeClient.onProgressChanged(current, progress);
+    }
+
+    // Reset the title and the icon based on the given item.
+    private void resetTitleAndIcon(WebView view) {
+        WebHistoryItem item = view.copyBackForwardList().getCurrentItem();
+        if (item != null) {
+            setUrlTitle(item.getUrl(), item.getTitle());
+            setFavicon(item.getFavicon());
+        } else {
+            setUrlTitle(null, null);
+            setFavicon(null);
+        }
+    }
+
+    /**
+     * Sets a title composed of the URL and the title string.
+     * @param url The URL of the site being loaded.
+     * @param title The title of the site being loaded.
+     */
+    private void setUrlTitle(String url, String title) {
+        mUrl = url;
+        mTitle = title;
+
+        // While the tab overview is animating or being shown, block changes
+        // to the title.
+        if (mAnimationCount == 0 && mTabOverview == null) {
+            setTitle(buildUrlTitle(url, title));
+        }
+    }
+
+    /**
+     * Builds and returns the page title, which is some
+     * combination of the page URL and title.
+     * @param url The URL of the site being loaded.
+     * @param title The title of the site being loaded.
+     * @return The page title.
+     */
+    private String buildUrlTitle(String url, String title) {
+        String urlTitle = "";
+
+        if (url != null) {
+            String titleUrl = buildTitleUrl(url);
+
+            if (title != null && 0 < title.length()) {
+                if (titleUrl != null && 0 < titleUrl.length()) {
+                    urlTitle = titleUrl + ": " + title;
+                } else {
+                    urlTitle = title;
+                }
+            } else {
+                if (titleUrl != null) {
+                    urlTitle = titleUrl;
+                }
+            }
+        }
+
+        return urlTitle;
+    }
+
+    /**
+     * @param url The URL to build a title version of the URL from.
+     * @return The title version of the URL or null if fails.
+     * The title version of the URL can be either the URL hostname,
+     * or the hostname with an "https://" prefix (for secure URLs),
+     * or an empty string if, for example, the URL in question is a
+     * file:// URL with no hostname.
+     */
+    private static String buildTitleUrl(String url) {
+        String titleUrl = null;
+
+        if (url != null) {
+            try {
+                // parse the url string
+                URL urlObj = new URL(url);
+                if (urlObj != null) {
+                    titleUrl = "";
+
+                    String protocol = urlObj.getProtocol();
+                    String host = urlObj.getHost();
+
+                    if (host != null && 0 < host.length()) {
+                        titleUrl = host;
+                        if (protocol != null) {
+                            // if a secure site, add an "https://" prefix!
+                            if (protocol.equalsIgnoreCase("https")) {
+                                titleUrl = protocol + "://" + host;
+                            }
+                        }
+                    }
+                }
+            } catch (MalformedURLException e) {}
+        }
+
+        return titleUrl;
+    }
+
+    // Set the favicon in the title bar.
+    private void setFavicon(Bitmap icon) {
+        // While the tab overview is animating or being shown, block changes to
+        // the favicon.
+        if (mAnimationCount > 0 || mTabOverview != null) {
+            return;
+        }
+        Drawable[] array = new Drawable[2];
+        PaintDrawable p = new PaintDrawable(Color.WHITE);
+        p.setCornerRadius(3f);
+        array[0] = p;
+        if (icon == null) {
+            array[1] = mGenericFavicon;
+        } else {
+            array[1] = new BitmapDrawable(icon);
+        }
+        LayerDrawable d = new LayerDrawable(array);
+        d.setLayerInset(1, 2, 2, 2, 2);
+        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, d);
+    }
+
+    /**
+     * Saves the current lock-icon state before resetting
+     * the lock icon. If we have an error, we may need to
+     * roll back to the previous state.
+     */
+    private void saveLockIcon() {
+        mPrevLockType = mLockIconType;
+    }
+
+    /**
+     * Reverts the lock-icon state to the last saved state,
+     * for example, if we had an error, and need to cancel
+     * the load.
+     */
+    private void revertLockIcon() {
+        mLockIconType = mPrevLockType;
+
+        if (Config.LOGV) {
+            Log.v(LOGTAG, "BrowserActivity.revertLockIcon:" +
+                  " revert lock icon to " + mLockIconType);
+        }
+
+        updateLockIconImage(mLockIconType);
+    }
+
+    private void switchTabs(int indexFrom, int indexToShow, boolean remove) {
+        int delay = TAB_ANIMATION_DURATION + TAB_OVERVIEW_DELAY;
+        // Animate to the tab picker, remove the current tab, then
+        // animate away from the tab picker to the parent WebView.
+        tabPicker(false, indexFrom, remove);
+        // Change to the parent tab
+        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
+        if (tab != null) {
+            sendAnimateFromOverview(tab, false, null, delay, null);
+        } else {
+            // Increment this here so that no other animations can happen in
+            // between the end of the tab picker transition and the beginning
+            // of openTabAndShow. This has a matching decrement in the handler
+            // of OPEN_TAB_AND_SHOW.
+            mAnimationCount++;
+            // Send a message to open a new tab.
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
+                        mSettings.getHomePage()), delay);
+        }
+    }
+
+    private void goBackOnePageOrQuit() {
+        TabControl.Tab current = mTabControl.getCurrentTab();
+        if (current == null) {
+            /*
+             * Instead of finishing the activity, simply push this to the back
+             * of the stack and let ActivityManager to choose the foreground
+             * activity. As BrowserActivity is singleTask, it will be always the
+             * root of the task. So we can use either true or false for
+             * moveTaskToBack().
+             */
+            moveTaskToBack(true);
+        }
+        WebView w = current.getWebView();
+        if (w.canGoBack()) {
+            w.goBack();
+        } else {
+            // Check to see if we are closing a window that was created by
+            // another window. If so, we switch back to that window.
+            TabControl.Tab parent = current.getParentTab();
+            if (parent != null) {
+                switchTabs(mTabControl.getCurrentIndex(),
+                        mTabControl.getTabIndex(parent), true);
+            } else {
+                if (current.closeOnExit()) {
+                    if (mTabControl.getTabCount() == 1) {
+                        finish();
+                        return;
+                    }
+                    // call pauseWebView() now, we won't be able to call it in
+                    // onPause() as the WebView won't be valid.
+                    pauseWebView();
+                    removeTabFromContentView(current);
+                    mTabControl.removeTab(current);
+                }
+                /*
+                 * Instead of finishing the activity, simply push this to the back
+                 * of the stack and let ActivityManager to choose the foreground
+                 * activity. As BrowserActivity is singleTask, it will be always the
+                 * root of the task. So we can use either true or false for
+                 * moveTaskToBack().
+                 */
+                moveTaskToBack(true);
+            }
+        }
+    }
+
+    public KeyTracker.State onKeyTracker(int keyCode,
+                                         KeyEvent event,
+                                         KeyTracker.Stage stage,
+                                         int duration) {
+        // if onKeyTracker() is called after activity onStop()
+        // because of accumulated key events,
+        // we should ignore it as browser is not active any more.
+        WebView topWindow = getTopWindow();
+        if (topWindow == null)
+            return KeyTracker.State.NOT_TRACKING;
+
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
+            // During animations, block the back key so that other animations
+            // are not triggered and so that we don't end up destroying all the
+            // WebViews before finishing the animation.
+            if (mAnimationCount > 0) {
+                return KeyTracker.State.DONE_TRACKING;
+            }
+            if (stage == KeyTracker.Stage.LONG_REPEAT) {
+                bookmarksOrHistoryPicker(true);
+                return KeyTracker.State.DONE_TRACKING;
+            } else if (stage == KeyTracker.Stage.UP) {
+                // FIXME: Currently, we do not have a notion of the
+                // history picker for the subwindow, but maybe we
+                // should?
+                WebView subwindow = mTabControl.getCurrentSubWindow();
+                if (subwindow != null) {
+                    if (subwindow.canGoBack()) {
+                        subwindow.goBack();
+                    } else {
+                        dismissSubWindow(mTabControl.getCurrentTab());
+                    }
+                } else {
+                    goBackOnePageOrQuit();
+                }
+                return KeyTracker.State.DONE_TRACKING;
+            }
+            return KeyTracker.State.KEEP_TRACKING;
+        }
+        return KeyTracker.State.NOT_TRACKING;
+    }
+
+    @Override public boolean onKeyDown(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_MENU) {
+            mMenuIsDown = true;
+        }
+        boolean handled =  mKeyTracker.doKeyDown(keyCode, event);
+        if (!handled) {
+            switch (keyCode) {
+                case KeyEvent.KEYCODE_SPACE:
+                    if (event.isShiftPressed()) {
+                        getTopWindow().pageUp(false);
+                    } else {
+                        getTopWindow().pageDown(false);
+                    }
+                    handled = true;
+                    break;
+
+                default:
+                    break;
+            }
+        }
+        return handled || super.onKeyDown(keyCode, event);
+    }
+
+    @Override public boolean onKeyUp(int keyCode, KeyEvent event) {
+        if (keyCode == KeyEvent.KEYCODE_MENU) {
+            mMenuIsDown = false;
+        }
+        return mKeyTracker.doKeyUp(keyCode, event) || super.onKeyUp(keyCode, event);
+    }
+
+    private void stopLoading() {
+        resetTitleAndRevertLockIcon();
+        WebView w = getTopWindow();
+        w.stopLoading();
+        mWebViewClient.onPageFinished(w, w.getUrl());
+
+        cancelStopToast();
+        mStopToast = Toast
+                .makeText(this, R.string.stopping, Toast.LENGTH_SHORT);
+        mStopToast.show();
+    }
+
+    private void cancelStopToast() {
+        if (mStopToast != null) {
+            mStopToast.cancel();
+            mStopToast = null;
+        }
+    }
+
+    // called by a non-UI thread to post the message
+    public void postMessage(int what, int arg1, int arg2, Object obj) {
+        mHandler.sendMessage(mHandler.obtainMessage(what, arg1, arg2, obj));
+    }
+
+    // public message ids
+    public final static int LOAD_URL                = 1001;
+    public final static int STOP_LOAD               = 1002;
+
+    // Message Ids
+    private static final int FOCUS_NODE_HREF         = 102;
+    private static final int CANCEL_CREDS_REQUEST    = 103;
+    private static final int ANIMATE_FROM_OVERVIEW   = 104;
+    private static final int ANIMATE_TO_OVERVIEW     = 105;
+    private static final int OPEN_TAB_AND_SHOW       = 106;
+    private static final int CHECK_MEMORY            = 107;
+    private static final int RELEASE_WAKELOCK        = 108;
+
+    // Private handler for handling javascript and saving passwords
+    private Handler mHandler = new Handler() {
+
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case ANIMATE_FROM_OVERVIEW:
+                    final HashMap map = (HashMap) msg.obj;
+                    animateFromTabOverview((AnimatingView) map.get("view"),
+                            msg.arg1 == 1, (Message) map.get("msg"));
+                    break;
+
+                case ANIMATE_TO_OVERVIEW:
+                    animateToTabOverview(msg.arg1, msg.arg2 == 1,
+                            (AnimatingView) msg.obj);
+                    break;
+
+                case OPEN_TAB_AND_SHOW:
+                    // Decrement mAnimationCount before openTabAndShow because
+                    // the method relies on the value being 0 to start the next
+                    // animation.
+                    mAnimationCount--;
+                    openTabAndShow((String) msg.obj, null, false);
+                    break;
+
+                case FOCUS_NODE_HREF:
+                    String url = (String) msg.getData().get("url");
+                    if (url == null || url.length() == 0) {
+                        break;
+                    }
+                    HashMap focusNodeMap = (HashMap) msg.obj;
+                    WebView view = (WebView) focusNodeMap.get("webview");
+                    // Only apply the action if the top window did not change.
+                    if (getTopWindow() != view) {
+                        break;
+                    }
+                    switch (msg.arg1) {
+                        case R.id.open_context_menu_id:
+                        case R.id.view_image_context_menu_id:
+                            loadURL(getTopWindow(), url);
+                            break;
+                        case R.id.open_newtab_context_menu_id:
+                            openTab(url);
+                            break;
+                        case R.id.bookmark_context_menu_id:
+                            Intent intent = new Intent(BrowserActivity.this,
+                                    AddBookmarkPage.class);
+                            intent.putExtra("url", url);
+                            startActivity(intent);
+                            break;
+                        case R.id.share_link_context_menu_id:
+                            Browser.sendString(BrowserActivity.this, url);
+                            break;
+                        case R.id.copy_link_context_menu_id:
+                            copy(url);
+                            break;
+                        case R.id.save_link_context_menu_id:
+                        case R.id.download_context_menu_id:
+                            onDownloadStartNoStream(url, null, null, null, -1);
+                            break;
+                    }
+                    break;
+
+                case LOAD_URL:
+                    loadURL(getTopWindow(), (String) msg.obj);
+                    break;
+
+                case STOP_LOAD:
+                    stopLoading();
+                    break;
+
+                case CANCEL_CREDS_REQUEST:
+                    resumeAfterCredentials();
+                    break;
+
+                case CHECK_MEMORY:
+                    // reschedule to check memory condition
+                    mHandler.removeMessages(CHECK_MEMORY);
+                    mHandler.sendMessageDelayed(mHandler.obtainMessage
+                            (CHECK_MEMORY), CHECK_MEMORY_INTERVAL);
+                    checkMemory();
+                    break;
+
+                case RELEASE_WAKELOCK:
+                    if (mWakeLock.isHeld()) {
+                        mWakeLock.release();
+                    }
+                    break;
+            }
+        }
+    };
+
+    // -------------------------------------------------------------------------
+    // WebViewClient implementation.
+    //-------------------------------------------------------------------------
+
+    // Use in overrideUrlLoading
+    /* package */ final static String SCHEME_WTAI = "wtai://wp/";
+    /* package */ final static String SCHEME_WTAI_MC = "wtai://wp/mc;";
+    /* package */ final static String SCHEME_WTAI_SD = "wtai://wp/sd;";
+    /* package */ final static String SCHEME_WTAI_AP = "wtai://wp/ap;";
+
+    /* package */ WebViewClient getWebViewClient() {
+        return mWebViewClient;
+    }
+
+    private void updateIcon(String url, Bitmap icon) {
+        if (icon != null) {
+            BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
+                    url, icon);
+        }
+        setFavicon(icon);
+    }
+
+    private final WebViewClient mWebViewClient = new WebViewClient() {
+        @Override
+        public void onPageStarted(WebView view, String url, Bitmap favicon) {
+            resetLockIcon(url);
+            setUrlTitle(url, null);
+            // Call updateIcon instead of setFavicon so the bookmark
+            // database can be updated.
+            updateIcon(url, favicon);
+
+            if (mSettings.isTracing() == true) {
+                // FIXME: we should save the trace file somewhere other than data.
+                // I can't use "/tmp" as it competes for system memory.
+                File file = getDir("browserTrace", 0);
+                String baseDir = file.getPath();
+                if (!baseDir.endsWith(File.separator)) baseDir += File.separator;
+                String host;
+                try {
+                    WebAddress uri = new WebAddress(url);
+                    host = uri.mHost;
+                } catch (android.net.ParseException ex) {
+                    host = "unknown_host";
+                }
+                host = host.replace('.', '_');
+                baseDir = baseDir + host;
+                file = new File(baseDir+".data");
+                if (file.exists() == true) {
+                    file.delete();
+                }
+                file = new File(baseDir+".key");
+                if (file.exists() == true) {
+                    file.delete();
+                }
+                mInTrace = true;
+                Debug.startMethodTracing(baseDir, 8 * 1024 * 1024);
+            }
+
+            // Performance probe
+            if (false) {
+                mStart = SystemClock.uptimeMillis();
+                mProcessStart = Process.getElapsedCpuTime();
+                long[] sysCpu = new long[7];
+                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
+                        sysCpu, null)) {
+                    mUserStart = sysCpu[0] + sysCpu[1];
+                    mSystemStart = sysCpu[2];
+                    mIdleStart = sysCpu[3];
+                    mIrqStart = sysCpu[4] + sysCpu[5] + sysCpu[6];
+                }
+                mUiStart = SystemClock.currentThreadTimeMillis();
+            }
+
+            if (!mPageStarted) {
+                mPageStarted = true;
+                // if onResume() has been called, resumeWebView() does nothing.
+                resumeWebView();
+            }
+
+            // reset sync timer to avoid sync starts during loading a page
+            CookieSyncManager.getInstance().resetSync();
+
+            mInLoad = true;
+            updateInLoadMenuItems();
+            if (!mIsNetworkUp) {
+                if ( mAlertDialog == null) {
+                    mAlertDialog = new AlertDialog.Builder(BrowserActivity.this)
+                        .setTitle(R.string.loadSuspendedTitle)
+                        .setMessage(R.string.loadSuspended)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+                }
+                if (view != null) {
+                    view.setNetworkAvailable(false);
+                }
+            }
+
+            // schedule to check memory condition
+            mHandler.sendMessageDelayed(mHandler.obtainMessage(CHECK_MEMORY),
+                    CHECK_MEMORY_INTERVAL);
+        }
+
+        @Override
+        public void onPageFinished(WebView view, String url) {
+            // Reset the title and icon in case we stopped a provisional
+            // load.
+            resetTitleAndIcon(view);
+
+            // Update the lock icon image only once we are done loading
+            updateLockIconImage(mLockIconType);
+
+            // Performance probe
+             if (false) {
+                long[] sysCpu = new long[7];
+                if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, null,
+                        sysCpu, null)) {
+                    String uiInfo = "UI thread used "
+                            + (SystemClock.currentThreadTimeMillis() - mUiStart)
+                            + " ms";
+                    if (Config.LOGD) {
+                        Log.d(LOGTAG, uiInfo);
+                    }
+                    //The string that gets written to the log
+                    String performanceString = "It took total "
+                            + (SystemClock.uptimeMillis() - mStart)
+                            + " ms clock time to load the page."
+                            + "\nbrowser process used "
+                            + (Process.getElapsedCpuTime() - mProcessStart)
+                            + " ms, user processes used "
+                            + (sysCpu[0] + sysCpu[1] - mUserStart) * 10
+                            + " ms, kernel used "
+                            + (sysCpu[2] - mSystemStart) * 10
+                            + " ms, idle took " + (sysCpu[3] - mIdleStart) * 10
+                            + " ms and irq took "
+                            + (sysCpu[4] + sysCpu[5] + sysCpu[6] - mIrqStart)
+                            * 10 + " ms, " + uiInfo;
+                    if (Config.LOGD) {
+                        Log.d(LOGTAG, performanceString + "\nWebpage: " + url);
+                    }
+                    if (url != null) {
+                        // strip the url to maintain consistency
+                        String newUrl = new String(url);
+                        if (newUrl.startsWith("http://www.")) {
+                            newUrl = newUrl.substring(11);
+                        } else if (newUrl.startsWith("http://")) {
+                            newUrl = newUrl.substring(7);
+                        } else if (newUrl.startsWith("https://www.")) {
+                            newUrl = newUrl.substring(12);
+                        } else if (newUrl.startsWith("https://")) {
+                            newUrl = newUrl.substring(8);
+                        }
+                        if (Config.LOGD) {
+                            Log.d(LOGTAG, newUrl + " loaded");
+                        }
+                        /*
+                        if (sWhiteList.contains(newUrl)) {
+                            // The string that gets pushed to the statistcs
+                            // service
+                            performanceString = performanceString
+                                    + "\nWebpage: "
+                                    + newUrl
+                                    + "\nCarrier: "
+                                    + android.os.SystemProperties
+                                            .get("gsm.sim.operator.alpha");
+                            if (mWebView != null
+                                    && mWebView.getContext() != null
+                                    && mWebView.getContext().getSystemService(
+                                    Context.CONNECTIVITY_SERVICE) != null) {
+                                ConnectivityManager cManager =
+                                        (ConnectivityManager) mWebView
+                                        .getContext().getSystemService(
+                                        Context.CONNECTIVITY_SERVICE);
+                                NetworkInfo nInfo = cManager
+                                        .getActiveNetworkInfo();
+                                if (nInfo != null) {
+                                    performanceString = performanceString
+                                            + "\nNetwork Type: "
+                                            + nInfo.getType().toString();
+                                }
+                            }
+                            Checkin.logEvent(mResolver,
+                                    Checkin.Events.Tag.WEBPAGE_LOAD,
+                                    performanceString);
+                            Log.w(LOGTAG, "pushed to the statistics service");
+                        }
+                        */
+                    }
+                }
+             }
+
+            if (mInTrace) {
+                mInTrace = false;
+                Debug.stopMethodTracing();
+            }
+
+            if (mPageStarted) {
+                mPageStarted = false;
+                // pauseWebView() will do nothing and return false if onPause()
+                // is not called yet.
+                if (pauseWebView()) {
+                    if (mWakeLock.isHeld()) {
+                        mHandler.removeMessages(RELEASE_WAKELOCK);
+                        mWakeLock.release();
+                    }
+                }
+            }
+
+            if (mInLoad) {
+                mInLoad = false;
+                updateInLoadMenuItems();
+            }
+
+            mHandler.removeMessages(CHECK_MEMORY);
+            checkMemory();
+        }
+
+        // return true if want to hijack the url to let another app to handle it
+        @Override
+        public boolean shouldOverrideUrlLoading(WebView view, String url) {
+            if (url.startsWith(SCHEME_WTAI)) {
+                // wtai://wp/mc;number
+                // number=string(phone-number)
+                if (url.startsWith(SCHEME_WTAI_MC)) {
+                    Intent intent = new Intent(Intent.ACTION_VIEW,
+                            Uri.parse(WebView.SCHEME_TEL +
+                            url.substring(SCHEME_WTAI_MC.length())));
+                    startActivity(intent);
+                    return true;
+                }
+                // wtai://wp/sd;dtmf
+                // dtmf=string(dialstring)
+                if (url.startsWith(SCHEME_WTAI_SD)) {
+                    // TODO
+                    // only send when there is active voice connection
+                    return false;
+                }
+                // wtai://wp/ap;number;name
+                // number=string(phone-number)
+                // name=string
+                if (url.startsWith(SCHEME_WTAI_AP)) {
+                    // TODO
+                    return false;
+                }
+            }
+
+            Uri uri;
+            try {
+                uri = Uri.parse(url);
+            } catch (IllegalArgumentException ex) {
+                return false;
+            }
+
+            // check whether other activities want to handle this url
+            Intent intent = new Intent(Intent.ACTION_VIEW, uri);
+            intent.addCategory(Intent.CATEGORY_BROWSABLE);
+            try {
+                if (startActivityIfNeeded(intent, -1)) {
+                    return true;
+                }
+            } catch (ActivityNotFoundException ex) {
+                // ignore the error. If no application can handle the URL,
+                // eg about:blank, assume the browser can handle it.
+            }
+
+            if (mMenuIsDown) {
+                openTab(url);
+                closeOptionsMenu();
+                return true;
+            }
+
+            return false;
+        }
+
+        /**
+         * Updates the lock icon. This method is called when we discover another
+         * resource to be loaded for this page (for example, javascript). While
+         * we update the icon type, we do not update the lock icon itself until
+         * we are done loading, it is slightly more secure this way.
+         */
+        @Override
+        public void onLoadResource(WebView view, String url) {
+            if (url != null && url.length() > 0) {
+                // It is only if the page claims to be secure
+                // that we may have to update the lock:
+                if (mLockIconType == LOCK_ICON_SECURE) {
+                    // If NOT a 'safe' url, change the lock to mixed content!
+                    if (!(URLUtil.isHttpsUrl(url) || URLUtil.isDataUrl(url) || URLUtil.isAboutUrl(url))) {
+                        mLockIconType = LOCK_ICON_MIXED;
+                        if (Config.LOGV) {
+                            Log.v(LOGTAG, "BrowserActivity.updateLockIcon:" +
+                                  " updated lock icon to " + mLockIconType + " due to " + url);
+                        }
+                    }
+                }
+            }
+        }
+
+        /**
+         * Show the dialog, asking the user if they would like to continue after
+         * an excessive number of HTTP redirects.
+         */
+        @Override
+        public void onTooManyRedirects(WebView view, final Message cancelMsg,
+                final Message continueMsg) {
+            new AlertDialog.Builder(BrowserActivity.this)
+                .setTitle(R.string.browserFrameRedirect)
+                .setMessage(R.string.browserFrame307Post)
+                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        continueMsg.sendToTarget();
+                    }})
+                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        cancelMsg.sendToTarget();
+                    }})
+                .setOnCancelListener(new OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        cancelMsg.sendToTarget();
+                    }})
+                .show();
+        }
+
+        /**
+         * Show a dialog informing the user of the network error reported by
+         * WebCore.
+         */
+        @Override
+        public void onReceivedError(WebView view, int errorCode,
+                String description, String failingUrl) {
+            if (errorCode != EventHandler.ERROR_LOOKUP &&
+                    errorCode != EventHandler.ERROR_CONNECT &&
+                    errorCode != EventHandler.ERROR_BAD_URL &&
+                    errorCode != EventHandler.ERROR_UNSUPPORTED_SCHEME &&
+                    errorCode != EventHandler.FILE_ERROR) {
+                new AlertDialog.Builder(BrowserActivity.this)
+                        .setTitle((errorCode == EventHandler.FILE_NOT_FOUND_ERROR) ?
+                                         R.string.browserFrameFileErrorLabel :
+                                         R.string.browserFrameNetworkErrorLabel)
+                        .setMessage(description)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+            }
+            Log.e(LOGTAG, "onReceivedError code:"+errorCode+" "+description);
+
+            // We need to reset the title after an error.
+            resetTitleAndRevertLockIcon();
+        }
+
+        /**
+         * Check with the user if it is ok to resend POST data as the page they
+         * are trying to navigate to is the result of a POST.
+         */
+        @Override
+        public void onFormResubmission(WebView view, final Message dontResend,
+                                       final Message resend) {
+            new AlertDialog.Builder(BrowserActivity.this)
+                .setTitle(R.string.browserFrameFormResubmitLabel)
+                .setMessage(R.string.browserFrameFormResubmitMessage)
+                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        resend.sendToTarget();
+                    }})
+                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        dontResend.sendToTarget();
+                    }})
+                .setOnCancelListener(new OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        dontResend.sendToTarget();
+                    }})
+                .show();
+        }
+
+        /**
+         * Insert the url into the visited history database.
+         * @param url The url to be inserted.
+         * @param isReload True if this url is being reloaded.
+         * FIXME: Not sure what to do when reloading the page.
+         */
+        @Override
+        public void doUpdateVisitedHistory(WebView view, String url,
+                boolean isReload) {
+            if (url.regionMatches(true, 0, "about:", 0, 6)) {
+                return;
+            }
+            Browser.updateVisitedHistory(mResolver, url, true);
+            WebIconDatabase.getInstance().retainIconForPageUrl(url);
+        }
+
+        /**
+         * Displays SSL error(s) dialog to the user.
+         */
+        @Override
+        public void onReceivedSslError(
+            final WebView view, final SslErrorHandler handler, final SslError error) {
+
+            if (mSettings.showSecurityWarnings()) {
+                final LayoutInflater factory =
+                    LayoutInflater.from(BrowserActivity.this);
+                final View warningsView =
+                    factory.inflate(R.layout.ssl_warnings, null);
+                final LinearLayout placeholder =
+                    (LinearLayout)warningsView.findViewById(R.id.placeholder);
+
+                if (error.hasError(SslError.SSL_UNTRUSTED)) {
+                    LinearLayout ll = (LinearLayout)factory
+                        .inflate(R.layout.ssl_warning, null);
+                    ((TextView)ll.findViewById(R.id.warning))
+                        .setText(R.string.ssl_untrusted);
+                    placeholder.addView(ll);
+                }
+
+                if (error.hasError(SslError.SSL_IDMISMATCH)) {
+                    LinearLayout ll = (LinearLayout)factory
+                        .inflate(R.layout.ssl_warning, null);
+                    ((TextView)ll.findViewById(R.id.warning))
+                        .setText(R.string.ssl_mismatch);
+                    placeholder.addView(ll);
+                }
+
+                if (error.hasError(SslError.SSL_EXPIRED)) {
+                    LinearLayout ll = (LinearLayout)factory
+                        .inflate(R.layout.ssl_warning, null);
+                    ((TextView)ll.findViewById(R.id.warning))
+                        .setText(R.string.ssl_expired);
+                    placeholder.addView(ll);
+                }
+
+                if (error.hasError(SslError.SSL_NOTYETVALID)) {
+                    LinearLayout ll = (LinearLayout)factory
+                        .inflate(R.layout.ssl_warning, null);
+                    ((TextView)ll.findViewById(R.id.warning))
+                        .setText(R.string.ssl_not_yet_valid);
+                    placeholder.addView(ll);
+                }
+
+                new AlertDialog.Builder(BrowserActivity.this)
+                    .setTitle(R.string.security_warning)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setView(warningsView)
+                    .setPositiveButton(R.string.ssl_continue,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    handler.proceed();
+                                }
+                            })
+                    .setNeutralButton(R.string.view_certificate,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    showSSLCertificateOnError(view, handler, error);
+                                }
+                            })
+                    .setNegativeButton(R.string.cancel,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog, int whichButton) {
+                                    handler.cancel();
+                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
+                                }
+                            })
+                    .setOnCancelListener(
+                            new DialogInterface.OnCancelListener() {
+                                public void onCancel(DialogInterface dialog) {
+                                    handler.cancel();
+                                    BrowserActivity.this.resetTitleAndRevertLockIcon();
+                                }
+                            })
+                    .show();
+            } else {
+                handler.proceed();
+            }
+        }
+
+        /**
+         * Handles an HTTP authentication request.
+         *
+         * @param handler The authentication handler
+         * @param host The host
+         * @param realm The realm
+         */
+        @Override
+        public void onReceivedHttpAuthRequest(WebView view,
+                final HttpAuthHandler handler, final String host, final String realm) {
+            String username = null;
+            String password = null;
+
+            boolean reuseHttpAuthUsernamePassword =
+                handler.useHttpAuthUsernamePassword();
+
+            if (reuseHttpAuthUsernamePassword &&
+                    (mTabControl.getCurrentWebView() != null)) {
+                String[] credentials =
+                        mTabControl.getCurrentWebView()
+                                .getHttpAuthUsernamePassword(host, realm);
+                if (credentials != null && credentials.length == 2) {
+                    username = credentials[0];
+                    password = credentials[1];
+                }
+            }
+
+            if (username != null && password != null) {
+                handler.proceed(username, password);
+            } else {
+                showHttpAuthentication(handler, host, realm, null, null, null, 0);
+            }
+        }
+
+        @Override
+        public boolean shouldOverrideKeyEvent(WebView view, KeyEvent event) {
+            if (mMenuIsDown) {
+                // only check shortcut key when MENU is held
+                return getWindow().isShortcutKey(event.getKeyCode(), event);
+            } else {
+                return false;
+            }
+        }
+
+        @Override
+        public void onUnhandledKeyEvent(WebView view, KeyEvent event) {
+            if (view != mTabControl.getCurrentTopWebView()) {
+                return;
+            }
+            if (event.isDown()) {
+                BrowserActivity.this.onKeyDown(event.getKeyCode(), event);
+            } else {
+                BrowserActivity.this.onKeyUp(event.getKeyCode(), event);
+            }
+        }
+    };
+
+    //--------------------------------------------------------------------------
+    // WebChromeClient implementation
+    //--------------------------------------------------------------------------
+
+    /* package */ WebChromeClient getWebChromeClient() {
+        return mWebChromeClient;
+    }
+
+    private final WebChromeClient mWebChromeClient = new WebChromeClient() {
+        // Helper method to create a new tab or sub window.
+        private void createWindow(final boolean dialog, final Message msg) {
+            if (dialog) {
+                mTabControl.createSubWindow();
+                final TabControl.Tab t = mTabControl.getCurrentTab();
+                attachSubWindow(t);
+                WebView.WebViewTransport transport =
+                        (WebView.WebViewTransport) msg.obj;
+                transport.setWebView(t.getSubWebView());
+                msg.sendToTarget();
+            } else {
+                final TabControl.Tab parent = mTabControl.getCurrentTab();
+                // openTabAndShow will dispatch the message after creating the
+                // new WebView. This will prevent another request from coming
+                // in during the animation.
+                openTabAndShow(null, msg, false);
+                parent.addChildTab(mTabControl.getCurrentTab());
+                WebView.WebViewTransport transport =
+                        (WebView.WebViewTransport) msg.obj;
+                transport.setWebView(mTabControl.getCurrentWebView());
+            }
+        }
+
+        @Override
+        public boolean onCreateWindow(WebView view, final boolean dialog,
+                final boolean userGesture, final Message resultMsg) {
+            // Ignore these requests during tab animations or if the tab
+            // overview is showing.
+            if (mAnimationCount > 0 || mTabOverview != null) {
+                return false;
+            }
+            // Short-circuit if we can't create any more tabs or sub windows.
+            if (dialog && mTabControl.getCurrentSubWindow() != null) {
+                new AlertDialog.Builder(BrowserActivity.this)
+                        .setTitle(R.string.too_many_subwindows_dialog_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.too_many_subwindows_dialog_message)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+                return false;
+            } else if (mTabControl.getTabCount() >= TabControl.MAX_TABS) {
+                new AlertDialog.Builder(BrowserActivity.this)
+                        .setTitle(R.string.too_many_windows_dialog_title)
+                        .setIcon(android.R.drawable.ic_dialog_alert)
+                        .setMessage(R.string.too_many_windows_dialog_message)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+                return false;
+            }
+
+            // Short-circuit if this was a user gesture.
+            if (userGesture) {
+                // createWindow will call openTabAndShow for new Windows and
+                // that will call tabPicker which will increment
+                // mAnimationCount.
+                createWindow(dialog, resultMsg);
+                return true;
+            }
+
+            // Allow the popup and create the appropriate window.
+            final AlertDialog.OnClickListener allowListener =
+                    new AlertDialog.OnClickListener() {
+                        public void onClick(DialogInterface d,
+                                int which) {
+                            // Same comment as above for setting
+                            // mAnimationCount.
+                            createWindow(dialog, resultMsg);
+                            // Since we incremented mAnimationCount while the
+                            // dialog was up, we have to decrement it here.
+                            mAnimationCount--;
+                        }
+                    };
+
+            // Block the popup by returning a null WebView.
+            final AlertDialog.OnClickListener blockListener =
+                    new AlertDialog.OnClickListener() {
+                        public void onClick(DialogInterface d, int which) {
+                            resultMsg.sendToTarget();
+                            // We are not going to trigger an animation so
+                            // unblock keys and animation requests.
+                            mAnimationCount--;
+                        }
+                    };
+
+            // Build a confirmation dialog to display to the user.
+            final AlertDialog d =
+                    new AlertDialog.Builder(BrowserActivity.this)
+                    .setTitle(R.string.attention)
+                    .setIcon(android.R.drawable.ic_dialog_alert)
+                    .setMessage(R.string.popup_window_attempt)
+                    .setPositiveButton(R.string.allow, allowListener)
+                    .setNegativeButton(R.string.block, blockListener)
+                    .setCancelable(false)
+                    .create();
+
+            // Show the confirmation dialog.
+            d.show();
+            // We want to increment mAnimationCount here to prevent a
+            // potential race condition. If the user allows a pop-up from a
+            // site and that pop-up then triggers another pop-up, it is
+            // possible to get the BACK key between here and when the dialog
+            // appears.
+            mAnimationCount++;
+            return true;
+        }
+
+        @Override
+        public void onCloseWindow(WebView window) {
+            final int currentIndex = mTabControl.getCurrentIndex();
+            final TabControl.Tab parent =
+                    mTabControl.getCurrentTab().getParentTab();
+            if (parent != null) {
+                // JavaScript can only close popup window.
+                switchTabs(currentIndex, mTabControl.getTabIndex(parent), true);
+            }
+        }
+
+        @Override
+        public void onProgressChanged(WebView view, int newProgress) {
+            // Block progress updates to the title bar while the tab overview
+            // is animating or being displayed.
+            if (mAnimationCount == 0 && mTabOverview == null) {
+                getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
+                        newProgress * 100);
+            }
+
+            if (newProgress == 100) {
+                // onProgressChanged() is called for sub-frame too while
+                // onPageFinished() is only called for the main frame. sync
+                // cookie and cache promptly here.
+                CookieSyncManager.getInstance().sync();
+            }
+        }
+
+        @Override
+        public void onReceivedTitle(WebView view, String title) {
+            String url = view.getOriginalUrl();
+
+            // here, if url is null, we want to reset the title
+            setUrlTitle(url, title);
+
+            if (url == null ||
+                url.length() >= SQLiteDatabase.SQLITE_MAX_LIKE_PATTERN_LENGTH) {
+                return;
+            }
+            if (url.startsWith("http://www.")) {
+                url = url.substring(11);
+            } else if (url.startsWith("http://")) {
+                url = url.substring(4);
+            }
+            try {
+                url = "%" + url;
+                String [] selArgs = new String[] { url };
+
+                String where = Browser.BookmarkColumns.URL + " LIKE ? AND "
+                        + Browser.BookmarkColumns.BOOKMARK + " = 0";
+                Cursor c = mResolver.query(Browser.BOOKMARKS_URI,
+                    Browser.HISTORY_PROJECTION, where, selArgs, null);
+                if (c.moveToFirst()) {
+                    if (Config.LOGV) {
+                        Log.v(LOGTAG, "updating cursor");
+                    }
+                    // Current implementation of database only has one entry per
+                    // url.
+                    int titleIndex =
+                            c.getColumnIndex(Browser.BookmarkColumns.TITLE);
+                    c.updateString(titleIndex, title);
+                    c.commitUpdates();
+                }
+                c.close();
+            } catch (IllegalStateException e) {
+                Log.e(LOGTAG, "BrowserActivity onReceived title", e);
+            } catch (SQLiteException ex) {
+                Log.e(LOGTAG, "onReceivedTitle() caught SQLiteException: ", ex);
+            }
+        }
+
+        @Override
+        public void onReceivedIcon(WebView view, Bitmap icon) {
+            updateIcon(view.getUrl(), icon);
+        }
+    };
+
+    /**
+     * Notify the host application a download should be done, or that
+     * the data should be streamed if a streaming viewer is available.
+     * @param url The full url to the content that should be downloaded
+     * @param contentDisposition Content-disposition http header, if
+     *                           present.
+     * @param mimetype The mimetype of the content reported by the server
+     * @param contentLength The file size reported by the server
+     */
+    public void onDownloadStart(String url, String userAgent,
+            String contentDisposition, String mimetype, long contentLength) {
+        // if we're dealing wih A/V content that's not explicitly marked
+        //     for download, check if it's streamable.
+        if (contentDisposition == null
+                        || !contentDisposition.regionMatches(true, 0, "attachment", 0, 10)) {
+            // query the package manager to see if there's a registered handler
+            //     that matches.
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setDataAndType(Uri.parse(url), mimetype);
+            if (getPackageManager().resolveActivity(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY) != null) {
+                // someone knows how to handle this mime type with this scheme, don't download.
+                try {
+                    startActivity(intent);
+                    return;
+                } catch (ActivityNotFoundException ex) {
+                    if (Config.LOGD) {
+                        Log.d(LOGTAG, "activity not found for " + mimetype
+                                + " over " + Uri.parse(url).getScheme(), ex);
+                    }
+                    // Best behavior is to fall back to a download in this case
+                }
+            }
+        }
+        onDownloadStartNoStream(url, userAgent, contentDisposition, mimetype, contentLength);
+    }
+
+    /**
+     * Notify the host application a download should be done, even if there
+     * is a streaming viewer available for thise type.
+     * @param url The full url to the content that should be downloaded
+     * @param contentDisposition Content-disposition http header, if
+     *                           present.
+     * @param mimetype The mimetype of the content reported by the server
+     * @param contentLength The file size reported by the server
+     */
+    /*package */ void onDownloadStartNoStream(String url, String userAgent,
+            String contentDisposition, String mimetype, long contentLength) {
+
+        String filename = URLUtil.guessFileName(url,
+                contentDisposition, mimetype);
+
+        // Check to see if we have an SDCard
+        String status = Environment.getExternalStorageState();
+        if (!status.equals(Environment.MEDIA_MOUNTED)) {
+            int title;
+            String msg;
+
+            // Check to see if the SDCard is busy, same as the music app
+            if (status.equals(Environment.MEDIA_SHARED)) {
+                msg = getString(R.string.download_sdcard_busy_dlg_msg);
+                title = R.string.download_sdcard_busy_dlg_title;
+            } else {
+                msg = getString(R.string.download_no_sdcard_dlg_msg, filename);
+                title = R.string.download_no_sdcard_dlg_title;
+            }
+
+            new AlertDialog.Builder(this)
+                .setTitle(title)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setMessage(msg)
+                .setPositiveButton(R.string.ok, null)
+                .show();
+            return;
+        }
+
+        // java.net.URI is a lot stricter than KURL so we have to undo
+        // KURL's percent-encoding and redo the encoding using java.net.URI.
+        URI uri = null;
+        try {
+            // Undo the percent-encoding that KURL may have done.
+            String newUrl = new String(URLUtil.decode(url.getBytes()));
+            // Parse the url into pieces
+            WebAddress w = new WebAddress(newUrl);
+            String frag = null;
+            String query = null;
+            String path = w.mPath;
+            // Break the path into path, query, and fragment
+            if (path.length() > 0) {
+                // Strip the fragment
+                int idx = path.lastIndexOf('#');
+                if (idx != -1) {
+                    frag = path.substring(idx + 1);
+                    path = path.substring(0, idx);
+                }
+                idx = path.lastIndexOf('?');
+                if (idx != -1) {
+                    query = path.substring(idx + 1);
+                    path = path.substring(0, idx);
+                }
+            }
+            uri = new URI(w.mScheme, w.mAuthInfo, w.mHost, w.mPort, path,
+                    query, frag);
+        } catch (Exception e) {
+            Log.e(LOGTAG, "Could not parse url for download: " + url, e);
+            return;
+        }
+
+        // XXX: Have to use the old url since the cookies were stored using the
+        // old percent-encoded url.
+        String cookies = CookieManager.getInstance().getCookie(url);
+
+        ContentValues values = new ContentValues();
+        values.put(Downloads.URI, uri.toString());
+        values.put(Downloads.COOKIE_DATA, cookies);
+        values.put(Downloads.USER_AGENT, userAgent);
+        values.put(Downloads.NOTIFICATION_PACKAGE,
+                getPackageName());
+        values.put(Downloads.NOTIFICATION_CLASS,
+                BrowserDownloadPage.class.getCanonicalName());
+        values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
+        values.put(Downloads.MIMETYPE, mimetype);
+        values.put(Downloads.FILENAME_HINT, filename);
+        values.put(Downloads.DESCRIPTION, uri.getHost());
+        if (contentLength > 0) {
+            values.put(Downloads.TOTAL_BYTES, contentLength);
+        }
+        if (mimetype == null) {
+            // We must have long pressed on a link or image to download it. We
+            // are not sure of the mimetype in this case, so do a head request
+            new FetchUrlMimeType(this).execute(values);
+        } else {
+            final Uri contentUri =
+                    getContentResolver().insert(Downloads.CONTENT_URI, values);
+            viewDownloads(contentUri);
+        }
+
+    }
+
+    /**
+     * Resets the lock icon. This method is called when we start a new load and
+     * know the url to be loaded.
+     */
+    private void resetLockIcon(String url) {
+        // Save the lock-icon state (we revert to it if the load gets cancelled)
+        saveLockIcon();
+
+        mLockIconType = LOCK_ICON_UNSECURE;
+        if (URLUtil.isHttpsUrl(url)) {
+            mLockIconType = LOCK_ICON_SECURE;
+            if (Config.LOGV) {
+                Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
+                      " reset lock icon to " + mLockIconType);
+            }
+        }
+
+        updateLockIconImage(LOCK_ICON_UNSECURE);
+    }
+
+    /**
+     * Resets the lock icon.  This method is called when the icon needs to be
+     * reset but we do not know whether we are loading a secure or not secure
+     * page.
+     */
+    private void resetLockIcon() {
+        // Save the lock-icon state (we revert to it if the load gets cancelled)
+        saveLockIcon();
+
+        mLockIconType = LOCK_ICON_UNSECURE;
+
+        if (Config.LOGV) {
+          Log.v(LOGTAG, "BrowserActivity.resetLockIcon:" +
+                " reset lock icon to " + mLockIconType);
+        }
+
+        updateLockIconImage(LOCK_ICON_UNSECURE);
+    }
+
+    /**
+     * Updates the lock-icon image in the title-bar.
+     */
+    private void updateLockIconImage(int lockIconType) {
+        Drawable d = null;
+        if (lockIconType == LOCK_ICON_SECURE) {
+            d = mSecLockIcon;
+        } else if (lockIconType == LOCK_ICON_MIXED) {
+            d = mMixLockIcon;
+        }
+        // If the tab overview is animating or being shown, do not update the
+        // lock icon.
+        if (mAnimationCount == 0 && mTabOverview == null) {
+            getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
+        }
+    }
+
+    /**
+     * Displays a page-info dialog.
+     * @param tab The tab to show info about
+     * @param fromShowSSLCertificateOnError The flag that indicates whether
+     * this dialog was opened from the SSL-certificate-on-error dialog or
+     * not. This is important, since we need to know whether to return to
+     * the parent dialog or simply dismiss.
+     */
+    private void showPageInfo(final TabControl.Tab tab,
+                              final boolean fromShowSSLCertificateOnError) {
+        final LayoutInflater factory = LayoutInflater
+                .from(this);
+
+        final View pageInfoView = factory.inflate(R.layout.page_info, null);
+
+        final WebView view = tab.getWebView();
+
+        String url = null;
+        String title = null;
+
+        if (view == null) {
+            url = tab.getUrl();
+            title = tab.getTitle();
+        } else if (view == mTabControl.getCurrentWebView()) {
+             // Use the cached title and url if this is the current WebView
+            url = mUrl;
+            title = mTitle;
+        } else {
+            url = view.getUrl();
+            title = view.getTitle();
+        }
+
+        if (url == null) {
+            url = "";
+        }
+        if (title == null) {
+            title = "";
+        }
+
+        ((TextView) pageInfoView.findViewById(R.id.address)).setText(url);
+        ((TextView) pageInfoView.findViewById(R.id.title)).setText(title);
+
+        mPageInfoView = tab;
+        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
+
+        AlertDialog.Builder alertDialogBuilder =
+            new AlertDialog.Builder(this)
+            .setTitle(R.string.page_info).setIcon(android.R.drawable.ic_dialog_info)
+            .setView(pageInfoView)
+            .setPositiveButton(
+                R.string.ok,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog,
+                                        int whichButton) {
+                        mPageInfoDialog = null;
+                        mPageInfoView = null;
+                        mPageInfoFromShowSSLCertificateOnError = null;
+
+                        // if we came here from the SSL error dialog
+                        if (fromShowSSLCertificateOnError) {
+                            // go back to the SSL error dialog
+                            showSSLCertificateOnError(
+                                mSSLCertificateOnErrorView,
+                                mSSLCertificateOnErrorHandler,
+                                mSSLCertificateOnErrorError);
+                        }
+                    }
+                })
+            .setOnCancelListener(
+                new DialogInterface.OnCancelListener() {
+                    public void onCancel(DialogInterface dialog) {
+                        mPageInfoDialog = null;
+                        mPageInfoView = null;
+                        mPageInfoFromShowSSLCertificateOnError = null;
+
+                        // if we came here from the SSL error dialog
+                        if (fromShowSSLCertificateOnError) {
+                            // go back to the SSL error dialog
+                            showSSLCertificateOnError(
+                                mSSLCertificateOnErrorView,
+                                mSSLCertificateOnErrorHandler,
+                                mSSLCertificateOnErrorError);
+                        }
+                    }
+                });
+
+        // if we have a main top-level page SSL certificate set or a certificate
+        // error
+        if (fromShowSSLCertificateOnError ||
+                (view != null && view.getCertificate() != null)) {
+            // add a 'View Certificate' button
+            alertDialogBuilder.setNeutralButton(
+                R.string.view_certificate,
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog,
+                                        int whichButton) {
+                        mPageInfoDialog = null;
+                        mPageInfoView = null;
+                        mPageInfoFromShowSSLCertificateOnError = null;
+
+                        // if we came here from the SSL error dialog
+                        if (fromShowSSLCertificateOnError) {
+                            // go back to the SSL error dialog
+                            showSSLCertificateOnError(
+                                mSSLCertificateOnErrorView,
+                                mSSLCertificateOnErrorHandler,
+                                mSSLCertificateOnErrorError);
+                        } else {
+                            // otherwise, display the top-most certificate from
+                            // the chain
+                            if (view.getCertificate() != null) {
+                                showSSLCertificate(tab);
+                            }
+                        }
+                    }
+                });
+        }
+
+        mPageInfoDialog = alertDialogBuilder.show();
+    }
+
+       /**
+     * Displays the main top-level page SSL certificate dialog
+     * (accessible from the Page-Info dialog).
+     * @param tab The tab to show certificate for.
+     */
+    private void showSSLCertificate(final TabControl.Tab tab) {
+        final View certificateView =
+                inflateCertificateView(tab.getWebView().getCertificate());
+        if (certificateView == null) {
+            return;
+        }
+
+        LayoutInflater factory = LayoutInflater.from(this);
+
+        final LinearLayout placeholder =
+                (LinearLayout)certificateView.findViewById(R.id.placeholder);
+
+        LinearLayout ll = (LinearLayout) factory.inflate(
+            R.layout.ssl_success, placeholder);
+        ((TextView)ll.findViewById(R.id.success))
+            .setText(R.string.ssl_certificate_is_valid);
+
+        mSSLCertificateView = tab;
+        mSSLCertificateDialog =
+            new AlertDialog.Builder(this)
+                .setTitle(R.string.ssl_certificate).setIcon(
+                    R.drawable.ic_dialog_browser_certificate_secure)
+                .setView(certificateView)
+                .setPositiveButton(R.string.ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog,
+                                    int whichButton) {
+                                mSSLCertificateDialog = null;
+                                mSSLCertificateView = null;
+
+                                showPageInfo(tab, false);
+                            }
+                        })
+                .setOnCancelListener(
+                        new DialogInterface.OnCancelListener() {
+                            public void onCancel(DialogInterface dialog) {
+                                mSSLCertificateDialog = null;
+                                mSSLCertificateView = null;
+
+                                showPageInfo(tab, false);
+                            }
+                        })
+                .show();
+    }
+
+    /**
+     * Displays the SSL error certificate dialog.
+     * @param view The target web-view.
+     * @param handler The SSL error handler responsible for cancelling the
+     * connection that resulted in an SSL error or proceeding per user request.
+     * @param error The SSL error object.
+     */
+    private void showSSLCertificateOnError(
+        final WebView view, final SslErrorHandler handler, final SslError error) {
+
+        final View certificateView =
+            inflateCertificateView(error.getCertificate());
+        if (certificateView == null) {
+            return;
+        }
+
+        LayoutInflater factory = LayoutInflater.from(this);
+
+        final LinearLayout placeholder =
+                (LinearLayout)certificateView.findViewById(R.id.placeholder);
+
+        if (error.hasError(SslError.SSL_UNTRUSTED)) {
+            LinearLayout ll = (LinearLayout)factory
+                .inflate(R.layout.ssl_warning, placeholder);
+            ((TextView)ll.findViewById(R.id.warning))
+                .setText(R.string.ssl_untrusted);
+        }
+
+        if (error.hasError(SslError.SSL_IDMISMATCH)) {
+            LinearLayout ll = (LinearLayout)factory
+                .inflate(R.layout.ssl_warning, placeholder);
+            ((TextView)ll.findViewById(R.id.warning))
+                .setText(R.string.ssl_mismatch);
+        }
+
+        if (error.hasError(SslError.SSL_EXPIRED)) {
+            LinearLayout ll = (LinearLayout)factory
+                .inflate(R.layout.ssl_warning, placeholder);
+            ((TextView)ll.findViewById(R.id.warning))
+                .setText(R.string.ssl_expired);
+        }
+
+        if (error.hasError(SslError.SSL_NOTYETVALID)) {
+            LinearLayout ll = (LinearLayout)factory
+                .inflate(R.layout.ssl_warning, placeholder);
+            ((TextView)ll.findViewById(R.id.warning))
+                .setText(R.string.ssl_not_yet_valid);
+        }
+
+        mSSLCertificateOnErrorHandler = handler;
+        mSSLCertificateOnErrorView = view;
+        mSSLCertificateOnErrorError = error;
+        mSSLCertificateOnErrorDialog =
+            new AlertDialog.Builder(this)
+                .setTitle(R.string.ssl_certificate).setIcon(
+                    R.drawable.ic_dialog_browser_certificate_partially_secure)
+                .setView(certificateView)
+                .setPositiveButton(R.string.ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog,
+                                    int whichButton) {
+                                mSSLCertificateOnErrorDialog = null;
+                                mSSLCertificateOnErrorView = null;
+                                mSSLCertificateOnErrorHandler = null;
+                                mSSLCertificateOnErrorError = null;
+
+                                mWebViewClient.onReceivedSslError(
+                                    view, handler, error);
+                            }
+                        })
+                 .setNeutralButton(R.string.page_info_view,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog,
+                                    int whichButton) {
+                                mSSLCertificateOnErrorDialog = null;
+
+                                // do not clear the dialog state: we will
+                                // need to show the dialog again once the
+                                // user is done exploring the page-info details
+
+                                showPageInfo(mTabControl.getTabFromView(view),
+                                        true);
+                            }
+                        })
+                .setOnCancelListener(
+                        new DialogInterface.OnCancelListener() {
+                            public void onCancel(DialogInterface dialog) {
+                                mSSLCertificateOnErrorDialog = null;
+                                mSSLCertificateOnErrorView = null;
+                                mSSLCertificateOnErrorHandler = null;
+                                mSSLCertificateOnErrorError = null;
+
+                                mWebViewClient.onReceivedSslError(
+                                    view, handler, error);
+                            }
+                        })
+                .show();
+    }
+
+    /**
+     * Inflates the SSL certificate view (helper method).
+     * @param certificate The SSL certificate.
+     * @return The resultant certificate view with issued-to, issued-by,
+     * issued-on, expires-on, and possibly other fields set.
+     * If the input certificate is null, returns null.
+     */
+    private View inflateCertificateView(SslCertificate certificate) {
+        if (certificate == null) {
+            return null;
+        }
+
+        LayoutInflater factory = LayoutInflater.from(this);
+
+        View certificateView = factory.inflate(
+            R.layout.ssl_certificate, null);
+
+        // issued to:
+        SslCertificate.DName issuedTo = certificate.getIssuedTo();
+        if (issuedTo != null) {
+            ((TextView) certificateView.findViewById(R.id.to_common))
+                .setText(issuedTo.getCName());
+            ((TextView) certificateView.findViewById(R.id.to_org))
+                .setText(issuedTo.getOName());
+            ((TextView) certificateView.findViewById(R.id.to_org_unit))
+                .setText(issuedTo.getUName());
+        }
+
+        // issued by:
+        SslCertificate.DName issuedBy = certificate.getIssuedBy();
+        if (issuedBy != null) {
+            ((TextView) certificateView.findViewById(R.id.by_common))
+                .setText(issuedBy.getCName());
+            ((TextView) certificateView.findViewById(R.id.by_org))
+                .setText(issuedBy.getOName());
+            ((TextView) certificateView.findViewById(R.id.by_org_unit))
+                .setText(issuedBy.getUName());
+        }
+
+        // issued on:
+        String issuedOn = reformatCertificateDate(
+            certificate.getValidNotBefore());
+        ((TextView) certificateView.findViewById(R.id.issued_on))
+            .setText(issuedOn);
+
+        // expires on:
+        String expiresOn = reformatCertificateDate(
+            certificate.getValidNotAfter());
+        ((TextView) certificateView.findViewById(R.id.expires_on))
+            .setText(expiresOn);
+
+        return certificateView;
+    }
+
+    /**
+     * Re-formats the certificate date (Date.toString()) string to
+     * a properly localized date string.
+     * @return Properly localized version of the certificate date string and
+     * the original certificate date string if fails to localize.
+     * If the original string is null, returns an empty string "".
+     */
+    private String reformatCertificateDate(String certificateDate) {
+      String reformattedDate = null;
+
+      if (certificateDate != null) {
+          Date date = null;
+          try {
+              date = java.text.DateFormat.getInstance().parse(certificateDate);
+          } catch (ParseException e) {
+              date = null;
+          }
+
+          if (date != null) {
+              reformattedDate =
+                  DateFormat.getDateFormat(this).format(date);
+          }
+      }
+
+      return reformattedDate != null ? reformattedDate :
+          (certificateDate != null ? certificateDate : "");
+    }
+
+    /**
+     * Displays an http-authentication dialog.
+     */
+    private void showHttpAuthentication(final HttpAuthHandler handler,
+            final String host, final String realm, final String title,
+            final String name, final String password, int focusId) {
+        LayoutInflater factory = LayoutInflater.from(this);
+        final View v = factory
+                .inflate(R.layout.http_authentication, null);
+        if (name != null) {
+            ((EditText) v.findViewById(R.id.username_edit)).setText(name);
+        }
+        if (password != null) {
+            ((EditText) v.findViewById(R.id.password_edit)).setText(password);
+        }
+
+        String titleText = title;
+        if (titleText == null) {
+            titleText = getText(R.string.sign_in_to).toString().replace(
+                    "%s1", host).replace("%s2", realm);
+        }
+
+        mHttpAuthHandler = handler;
+        AlertDialog dialog = new AlertDialog.Builder(this)
+                .setTitle(titleText)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setView(v)
+                .setPositiveButton(R.string.action,
+                        new DialogInterface.OnClickListener() {
+                             public void onClick(DialogInterface dialog,
+                                     int whichButton) {
+                                String nm = ((EditText) v
+                                        .findViewById(R.id.username_edit))
+                                        .getText().toString();
+                                String pw = ((EditText) v
+                                        .findViewById(R.id.password_edit))
+                                        .getText().toString();
+                                BrowserActivity.this.setHttpAuthUsernamePassword
+                                        (host, realm, nm, pw);
+                                handler.proceed(nm, pw);
+                                mHttpAuthenticationDialog = null;
+                                mHttpAuthHandler = null;
+                            }})
+                .setNegativeButton(R.string.cancel,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog,
+                                    int whichButton) {
+                                handler.cancel();
+                                BrowserActivity.this.resetTitleAndRevertLockIcon();
+                                mHttpAuthenticationDialog = null;
+                                mHttpAuthHandler = null;
+                            }})
+                .setOnCancelListener(new DialogInterface.OnCancelListener() {
+                        public void onCancel(DialogInterface dialog) {
+                            handler.cancel();
+                            BrowserActivity.this.resetTitleAndRevertLockIcon();
+                            mHttpAuthenticationDialog = null;
+                            mHttpAuthHandler = null;
+                        }})
+                .create();
+        // Make the IME appear when the dialog is displayed if applicable.
+        dialog.getWindow().setSoftInputMode(
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+        dialog.show();
+        if (focusId != 0) {
+            dialog.findViewById(focusId).requestFocus();
+        } else {
+            v.findViewById(R.id.username_edit).requestFocus();
+        }
+        mHttpAuthenticationDialog = dialog;
+    }
+
+    public int getProgress() {
+        WebView w = mTabControl.getCurrentWebView();
+        if (w != null) {
+            return w.getProgress();
+        } else {
+            return 100;
+        }
+    }
+
+    /**
+     * Set HTTP authentication password.
+     *
+     * @param host The host for the password
+     * @param realm The realm for the password
+     * @param username The username for the password. If it is null, it means
+     *            password can't be saved.
+     * @param password The password
+     */
+    public void setHttpAuthUsernamePassword(String host, String realm,
+                                            String username,
+                                            String password) {
+        WebView w = mTabControl.getCurrentWebView();
+        if (w != null) {
+            w.setHttpAuthUsernamePassword(host, realm, username, password);
+        }
+    }
+
+    /**
+     * connectivity manager says net has come or gone... inform the user
+     * @param up true if net has come up, false if net has gone down
+     */
+    public void onNetworkToggle(boolean up) {
+        if (up == mIsNetworkUp) {
+            return;
+        } else if (up) {
+            mIsNetworkUp = true;
+            if (mAlertDialog != null) {
+                mAlertDialog.cancel();
+                mAlertDialog = null;
+            }
+        } else {
+            mIsNetworkUp = false;
+            if (mInLoad && mAlertDialog == null) {
+                mAlertDialog = new AlertDialog.Builder(this)
+                        .setTitle(R.string.loadSuspendedTitle)
+                        .setMessage(R.string.loadSuspended)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+            }
+        }
+        WebView w = mTabControl.getCurrentWebView();
+        if (w != null) {
+            w.setNetworkAvailable(up);
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+                                    Intent intent) {
+        switch (requestCode) {
+            case COMBO_PAGE:
+                if (resultCode == RESULT_OK && intent != null) {
+                    String data = intent.getAction();
+                    Bundle extras = intent.getExtras();
+                    if (extras != null && extras.getBoolean("new_window", false)) {
+                        openTab(data);
+                    } else {
+                        final TabControl.Tab currentTab =
+                                mTabControl.getCurrentTab();
+                        // If the Window overview is up and we are not in the
+                        // middle of an animation, animate away from it to the
+                        // current tab.
+                        if (mTabOverview != null && mAnimationCount == 0) {
+                            sendAnimateFromOverview(currentTab, false, data,
+                                    TAB_OVERVIEW_DELAY, null);
+                        } else {
+                            dismissSubWindow(currentTab);
+                            if (data != null && data.length() != 0) {
+                                getTopWindow().loadUrl(data);
+                            }
+                        }
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+        getTopWindow().requestFocus();
+    }
+
+    /*
+     * This method is called as a result of the user selecting the options
+     * menu to see the download window, or when a download changes state. It
+     * shows the download window ontop of the current window.
+     */
+    /* package */ void viewDownloads(Uri downloadRecord) {
+        Intent intent = new Intent(this,
+                BrowserDownloadPage.class);
+        intent.setData(downloadRecord);
+        startActivityForResult(intent, this.DOWNLOAD_PAGE);
+
+    }
+
+    /**
+     * Handle results from Tab Switcher mTabOverview tool
+     */
+    private class TabListener implements ImageGrid.Listener {
+        public void remove(int position) {
+            // Note: Remove is not enabled if we have only one tab.
+            if (Config.DEBUG && mTabControl.getTabCount() == 1) {
+                throw new AssertionError();
+            }
+
+            // Remember the current tab.
+            TabControl.Tab current = mTabControl.getCurrentTab();
+            final TabControl.Tab remove = mTabControl.getTab(position);
+            mTabControl.removeTab(remove);
+            // If we removed the current tab, use the tab at position - 1 if
+            // possible.
+            if (current == remove) {
+                // If the user removes the last tab, act like the New Tab item
+                // was clicked on.
+                if (mTabControl.getTabCount() == 0) {
+                    current = mTabControl.createNewTab(false);
+                    sendAnimateFromOverview(current, true,
+                            mSettings.getHomePage(), TAB_OVERVIEW_DELAY, null);
+                } else {
+                    final int index = position > 0 ? (position - 1) : 0;
+                    current = mTabControl.getTab(index);
+                }
+            }
+
+            // The tab overview could have been dismissed before this method is
+            // called.
+            if (mTabOverview != null) {
+                // Remove the tab and change the index.
+                mTabOverview.remove(position);
+                mTabOverview.setCurrentIndex(mTabControl.getTabIndex(current));
+            }
+
+            // Only the current tab ensures its WebView is non-null. This
+            // implies that we are reloading the freed tab.
+            mTabControl.setCurrentTab(current);
+        }
+        public void onClick(int index) {
+            // Change the tab if necessary.
+            // Index equals ImageGrid.CANCEL when pressing back from the tab
+            // overview.
+            if (index == ImageGrid.CANCEL) {
+                index = mTabControl.getCurrentIndex();
+                // The current index is -1 if the current tab was removed.
+                if (index == -1) {
+                    // Take the last tab as a fallback.
+                    index = mTabControl.getTabCount() - 1;
+                }
+            }
+
+            // Clear all the data for tab picker so next time it will be
+            // recreated.
+            mTabControl.wipeAllPickerData();
+
+            // NEW_TAB means that the "New Tab" cell was clicked on.
+            if (index == ImageGrid.NEW_TAB) {
+                openTabAndShow(mSettings.getHomePage(), null, false);
+            } else {
+                sendAnimateFromOverview(mTabControl.getTab(index),
+                        false, null, 0, null);
+            }
+        }
+    }
+
+    // A fake View that draws the WebView's picture with a fast zoom filter.
+    // The View is used in case the tab is freed during the animation because
+    // of low memory.
+    private static class AnimatingView extends View {
+        private static final int ZOOM_BITS = Paint.FILTER_BITMAP_FLAG |
+                Paint.DITHER_FLAG | Paint.SUBPIXEL_TEXT_FLAG;
+        private static final DrawFilter sZoomFilter =
+                new PaintFlagsDrawFilter(ZOOM_BITS, Paint.LINEAR_TEXT_FLAG);
+        private final Picture mPicture;
+        private final float   mScale;
+        private final int     mScrollX;
+        private final int     mScrollY;
+        final TabControl.Tab  mTab;
+
+        AnimatingView(Context ctxt, TabControl.Tab t) {
+            super(ctxt);
+            mTab = t;
+            // Use the top window in the animation since the tab overview will
+            // display the top window in each cell.
+            final WebView w = t.getTopWindow();
+            mPicture = w.capturePicture();
+            mScale = w.getScale() / w.getWidth();
+            mScrollX = w.getScrollX();
+            mScrollY = w.getScrollY();
+        }
+
+        @Override
+        protected void onDraw(Canvas canvas) {
+            canvas.save();
+            canvas.drawColor(Color.WHITE);
+            if (mPicture != null) {
+                canvas.setDrawFilter(sZoomFilter);
+                float scale = getWidth() * mScale;
+                canvas.scale(scale, scale);
+                canvas.translate(-mScrollX, -mScrollY);
+                canvas.drawPicture(mPicture);
+            }
+            canvas.restore();
+        }
+    }
+
+    /**
+     *  Open the tab picker. This function will always use the current tab in
+     *  its animation.
+     *  @param stay boolean stating whether the tab picker is to remain open
+     *          (in which case it needs a listener and its menu) or not.
+     *  @param index The index of the tab to show as the selection in the tab
+     *               overview.
+     *  @param remove If true, the tab at index will be removed after the
+     *                animation completes.
+     */
+    private void tabPicker(final boolean stay, final int index,
+            final boolean remove) {
+        if (mTabOverview != null) {
+            return;
+        }
+
+        int size = mTabControl.getTabCount();
+
+        TabListener l = null;
+        if (stay) {
+            l = mTabListener = new TabListener();
+        }
+        mTabOverview = new ImageGrid(this, stay, l);
+
+        for (int i = 0; i < size; i++) {
+            final TabControl.Tab t = mTabControl.getTab(i);
+            mTabControl.populatePickerData(t);
+            mTabOverview.add(t);
+        }
+
+        // Tell the tab overview to show the current tab, the tab overview will
+        // handle the "New Tab" case.
+        int currentIndex = mTabControl.getCurrentIndex();
+        mTabOverview.setCurrentIndex(currentIndex);
+
+        // Attach the tab overview.
+        mContentView.addView(mTabOverview, COVER_SCREEN_PARAMS);
+
+        // Create a fake AnimatingView to animate the WebView's picture.
+        final TabControl.Tab current = mTabControl.getCurrentTab();
+        final AnimatingView v = new AnimatingView(this, current);
+        mContentView.addView(v, COVER_SCREEN_PARAMS);
+        removeTabFromContentView(current);
+        // Pause timers to get the animation smoother.
+        current.getWebView().pauseTimers();
+
+        // Send a message so the tab picker has a chance to layout and get
+        // positions for all the cells.
+        mHandler.sendMessage(mHandler.obtainMessage(ANIMATE_TO_OVERVIEW,
+                index, remove ? 1 : 0, v));
+        // Setting this will indicate that we are animating to the overview. We
+        // set it here to prevent another request to animate from coming in
+        // between now and when ANIMATE_TO_OVERVIEW is handled.
+        mAnimationCount++;
+        // Always change the title bar to the window overview title while
+        // animating.
+        getWindow().setFeatureDrawable(Window.FEATURE_LEFT_ICON, null);
+        getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, null);
+        getWindow().setFeatureInt(Window.FEATURE_PROGRESS,
+                Window.PROGRESS_VISIBILITY_OFF);
+        setTitle(R.string.tab_picker_title);
+        // Make the menu empty until the animation completes.
+        mMenuState = EMPTY_MENU;
+    }
+
+    private void bookmarksOrHistoryPicker(boolean startWithHistory) {
+        WebView current = mTabControl.getCurrentWebView();
+        if (current == null) {
+            return;
+        }
+        Intent intent = new Intent(this,
+                CombinedBookmarkHistoryActivity.class);
+        String title = current.getTitle();
+        String url = current.getUrl();
+        // Just in case the user opens bookmarks before a page finishes loading
+        // so the current history item, and therefore the page, is null.
+        if (null == url) {
+            url = mLastEnteredUrl;
+            // This can happen.
+            if (null == url) {
+                url = mSettings.getHomePage();
+            }
+        }
+        // In case the web page has not yet received its associated title.
+        if (title == null) {
+            title = url;
+        }
+        intent.putExtra("title", title);
+        intent.putExtra("url", url);
+        intent.putExtra("maxTabsOpen",
+                mTabControl.getTabCount() >= TabControl.MAX_TABS);
+        if (startWithHistory) {
+            intent.putExtra(CombinedBookmarkHistoryActivity.STARTING_TAB,
+                    CombinedBookmarkHistoryActivity.HISTORY_TAB);
+        }
+        startActivityForResult(intent, COMBO_PAGE);
+    }
+
+    // Called when loading from context menu or LOAD_URL message
+    private void loadURL(WebView view, String url) {
+        // In case the user enters nothing.
+        if (url != null && url.length() != 0 && view != null) {
+            url = smartUrlFilter(url);
+            if (!mWebViewClient.shouldOverrideUrlLoading(view, url)) {
+                view.loadUrl(url);
+            }
+        }
+    }
+
+    private void checkMemory() {
+        ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo();
+        ((ActivityManager) getSystemService(ACTIVITY_SERVICE))
+                .getMemoryInfo(mi);
+        // FIXME: mi.lowMemory is too aggressive, use (mi.availMem <
+        // mi.threshold) for now
+        //        if (mi.lowMemory) {
+        if (mi.availMem < mi.threshold) {
+            Log.w(LOGTAG, "Browser is freeing memory now because: available="
+                            + (mi.availMem / 1024) + "K threshold="
+                            + (mi.threshold / 1024) + "K");
+            mTabControl.freeMemory();
+        }
+    }
+
+    private String smartUrlFilter(Uri inUri) {
+        if (inUri != null) {
+            return smartUrlFilter(inUri.toString());
+        }
+        return null;
+    }
+
+
+    // get window count
+
+    int getWindowCount(){
+      if(mTabControl != null){
+        return mTabControl.getTabCount();
+      }
+      return 0;
+    }
+
+    static final Pattern ACCEPTED_URI_SCHEMA = Pattern.compile(
+            "(?i)" + // switch on case insensitive matching
+            "(" +    // begin group for schema
+            "(?:http|https|file):\\/\\/" +
+            "|(?:data|about|content|javascript):" +
+            ")" +
+            "(.*)" );
+
+    /**
+     * Attempts to determine whether user input is a URL or search
+     * terms.  Anything with a space is passed to search.
+     *
+     * Converts to lowercase any mistakenly uppercased schema (i.e.,
+     * "Http://" converts to "http://"
+     *
+     * @return Original or modified URL
+     *
+     */
+    String smartUrlFilter(String url) {
+
+        String inUrl = url.trim();
+        boolean hasSpace = inUrl.indexOf(' ') != -1;
+
+        Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
+        if (matcher.matches()) {
+            if (hasSpace) {
+                inUrl = inUrl.replace(" ", "%20");
+            }
+            // force scheme to lowercase
+            String scheme = matcher.group(1);
+            String lcScheme = scheme.toLowerCase();
+            if (!lcScheme.equals(scheme)) {
+                return lcScheme + matcher.group(2);
+            }
+            return inUrl;
+        }
+        if (hasSpace) {
+            // FIXME: quick search, need to be customized by setting
+            if (inUrl.length() > 2 && inUrl.charAt(1) == ' ') {
+                // FIXME: Is this the correct place to add to searches?
+                // what if someone else calls this function?
+                char char0 = inUrl.charAt(0);
+
+                if (char0 == 'g') {
+                    Browser.addSearchUrl(mResolver, inUrl);
+                    return composeSearchUrl(inUrl.substring(2));
+
+                } else if (char0 == 'w') {
+                    Browser.addSearchUrl(mResolver, inUrl);
+                    return URLUtil.composeSearchUrl(inUrl.substring(2),
+                            QuickSearch_W,
+                            QUERY_PLACE_HOLDER);
+
+                } else if (char0 == 'd') {
+                    Browser.addSearchUrl(mResolver, inUrl);
+                    return URLUtil.composeSearchUrl(inUrl.substring(2),
+                            QuickSearch_D,
+                            QUERY_PLACE_HOLDER);
+
+                } else if (char0 == 'l') {
+                    Browser.addSearchUrl(mResolver, inUrl);
+                    // FIXME: we need location in this case
+                    return URLUtil.composeSearchUrl(inUrl.substring(2),
+                            QuickSearch_L,
+                            QUERY_PLACE_HOLDER);
+                }
+            }
+        } else {
+            if (Regex.WEB_URL_PATTERN.matcher(inUrl).matches()) {
+                return URLUtil.guessUrl(inUrl);
+            }
+        }
+
+        Browser.addSearchUrl(mResolver, inUrl);
+        return composeSearchUrl(inUrl);
+    }
+
+    /* package */ String composeSearchUrl(String search) {
+        return URLUtil.composeSearchUrl(search, QuickSearch_G,
+                QUERY_PLACE_HOLDER);
+    }
+
+    /* package */void setBaseSearchUrl(String url) {
+        if (url == null || url.length() == 0) {
+            /*
+             * get the google search url based on the SIM. Default is US. NOTE:
+             * This code uses resources to optionally select the search Uri,
+             * based on the MCC value from the SIM. The default string will most
+             * likely be fine. It is parameterized to accept info from the
+             * Locale, the language code is the first parameter (%1$s) and the
+             * country code is the second (%2$s). This code must function in the
+             * same way as a similar lookup in
+             * com.android.googlesearch.SuggestionProvider#onCreate(). If you
+             * change either of these functions, change them both. (The same is
+             * true for the underlying resource strings, which are stored in
+             * mcc-specific xml files.)
+             */
+            Locale l = Locale.getDefault();
+            QuickSearch_G = getResources().getString(
+                    R.string.google_search_base, l.getLanguage(),
+                    l.getCountry().toLowerCase())
+                    + "client=ms-"
+                    + SystemProperties.get("persist.sys.com.google.clientid", "unknown")
+                    + "&source=android-" + GOOGLE_SEARCH_SOURCE_SUGGEST + "&q=%s";
+        } else {
+            QuickSearch_G = url;
+        }
+    }
+
+    private final static int LOCK_ICON_UNSECURE = 0;
+    private final static int LOCK_ICON_SECURE   = 1;
+    private final static int LOCK_ICON_MIXED    = 2;
+
+    private int mLockIconType = LOCK_ICON_UNSECURE;
+    private int mPrevLockType = LOCK_ICON_UNSECURE;
+
+    private BrowserSettings mSettings;
+    private TabControl      mTabControl;
+    private ContentResolver mResolver;
+    private FrameLayout     mContentView;
+    private ImageGrid       mTabOverview;
+
+    // FIXME, temp address onPrepareMenu performance problem. When we move everything out of
+    // view, we should rewrite this.
+    private int mCurrentMenuState = 0;
+    private int mMenuState = R.id.MAIN_MENU;
+    private static final int EMPTY_MENU = -1;
+    private Menu mMenu;
+
+    private FindDialog mFindDialog;
+    // Used to prevent chording to result in firing two shortcuts immediately
+    // one after another.  Fixes bug 1211714.
+    boolean mCanChord;
+
+    private boolean mInLoad;
+    private boolean mIsNetworkUp;
+
+    private boolean mPageStarted;
+    private boolean mActivityInPause = true;
+
+    private boolean mMenuIsDown;
+
+    private final KeyTracker mKeyTracker = new KeyTracker(this);
+
+    // As trackball doesn't send repeat down, we have to track it ourselves
+    private boolean mTrackTrackball;
+
+    private static boolean mInTrace;
+
+    // Performance probe
+    private static final int[] SYSTEM_CPU_FORMAT = new int[] {
+            Process.PROC_SPACE_TERM | Process.PROC_COMBINE,
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 1: user time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 2: nice time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 3: sys time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 4: idle time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 5: iowait time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG, // 6: irq time
+            Process.PROC_SPACE_TERM | Process.PROC_OUT_LONG  // 7: softirq time
+    };
+
+    private long mStart;
+    private long mProcessStart;
+    private long mUserStart;
+    private long mSystemStart;
+    private long mIdleStart;
+    private long mIrqStart;
+
+    private long mUiStart;
+
+    private Drawable    mMixLockIcon;
+    private Drawable    mSecLockIcon;
+    private Drawable    mGenericFavicon;
+
+    /* hold a ref so we can auto-cancel if necessary */
+    private AlertDialog mAlertDialog;
+
+    // Wait for credentials before loading google.com
+    private ProgressDialog mCredsDlg;
+
+    // The up-to-date URL and title (these can be different from those stored
+    // in WebView, since it takes some time for the information in WebView to
+    // get updated)
+    private String mUrl;
+    private String mTitle;
+
+    // As PageInfo has different style for landscape / portrait, we have
+    // to re-open it when configuration changed
+    private AlertDialog mPageInfoDialog;
+    private TabControl.Tab mPageInfoView;
+    // If the Page-Info dialog is launched from the SSL-certificate-on-error
+    // dialog, we should not just dismiss it, but should get back to the
+    // SSL-certificate-on-error dialog. This flag is used to store this state
+    private Boolean mPageInfoFromShowSSLCertificateOnError;
+
+    // as SSLCertificateOnError has different style for landscape / portrait,
+    // we have to re-open it when configuration changed
+    private AlertDialog mSSLCertificateOnErrorDialog;
+    private WebView mSSLCertificateOnErrorView;
+    private SslErrorHandler mSSLCertificateOnErrorHandler;
+    private SslError mSSLCertificateOnErrorError;
+
+    // as SSLCertificate has different style for landscape / portrait, we
+    // have to re-open it when configuration changed
+    private AlertDialog mSSLCertificateDialog;
+    private TabControl.Tab mSSLCertificateView;
+
+    // as HttpAuthentication has different style for landscape / portrait, we
+    // have to re-open it when configuration changed
+    private AlertDialog mHttpAuthenticationDialog;
+    private HttpAuthHandler mHttpAuthHandler;
+
+    /*package*/ static final FrameLayout.LayoutParams COVER_SCREEN_PARAMS =
+                                            new FrameLayout.LayoutParams(
+                                            ViewGroup.LayoutParams.FILL_PARENT,
+                                            ViewGroup.LayoutParams.FILL_PARENT);
+    // We may provide UI to customize these
+    // Google search from the browser
+    static String QuickSearch_G;
+    // Wikipedia search
+    final static String QuickSearch_W = "http://en.wikipedia.org/w/index.php?search=%s&go=Go";
+    // Dictionary search
+    final static String QuickSearch_D = "http://dictionary.reference.com/search?q=%s";
+    // Google Mobile Local search
+    final static String QuickSearch_L = "http://www.google.com/m/search?site=local&q=%s&near=mountain+view";
+
+    final static String QUERY_PLACE_HOLDER = "%s";
+
+    // "source" parameter for Google search through search key
+    final static String GOOGLE_SEARCH_SOURCE_SEARCHKEY = "browser-key";
+    // "source" parameter for Google search through goto menu
+    final static String GOOGLE_SEARCH_SOURCE_GOTO = "browser-goto";
+    // "source" parameter for Google search through simplily type
+    final static String GOOGLE_SEARCH_SOURCE_TYPE = "browser-type";
+    // "source" parameter for Google search suggested by the browser
+    final static String GOOGLE_SEARCH_SOURCE_SUGGEST = "browser-suggest";
+    // "source" parameter for Google search from unknown source
+    final static String GOOGLE_SEARCH_SOURCE_UNKNOWN = "unknown";
+
+    private final static String LOGTAG = "browser";
+
+    private TabListener mTabListener;
+
+    private String mLastEnteredUrl;
+
+    private PowerManager.WakeLock mWakeLock;
+    private final static int WAKELOCK_TIMEOUT = 5 * 60 * 1000; // 5 minutes
+
+    private Toast mStopToast;
+
+    // Used during animations to prevent other animations from being triggered.
+    // A count is used since the animation to and from the Window overview can
+    // overlap. A count of 0 means no animation where a count of > 0 means
+    // there are animations in progress.
+    private int mAnimationCount;
+
+    // As the ids are dynamically created, we can't guarantee that they will
+    // be in sequence, so this static array maps ids to a window number.
+    final static private int[] WINDOW_SHORTCUT_ID_ARRAY =
+    { R.id.window_one_menu_id, R.id.window_two_menu_id, R.id.window_three_menu_id,
+      R.id.window_four_menu_id, R.id.window_five_menu_id, R.id.window_six_menu_id,
+      R.id.window_seven_menu_id, R.id.window_eight_menu_id };
+
+    // monitor platform changes
+    private IntentFilter mNetworkStateChangedFilter;
+    private BroadcastReceiver mNetworkStateIntentReceiver;
+
+    // activity requestCode
+    final static int COMBO_PAGE             = 1;
+    final static int DOWNLOAD_PAGE          = 2;
+    final static int PREFERENCES_PAGE       = 3;
+
+    // the frenquency of checking whether system memory is low
+    final static int CHECK_MEMORY_INTERVAL = 30000;     // 30 seconds
+}
diff --git a/src/com/android/browser/BrowserBookmarksAdapter.java b/src/com/android/browser/BrowserBookmarksAdapter.java
new file mode 100644
index 0000000..479dc0e
--- /dev/null
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -0,0 +1,535 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Browser;
+import android.provider.Browser.BookmarkColumns;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.WebIconDatabase;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.BaseAdapter;
+
+import java.io.ByteArrayOutputStream;
+
+class BrowserBookmarksAdapter extends BaseAdapter {
+
+    private final String            LOGTAG = "Bookmarks";
+
+    private String                  mCurrentPage;
+    private Cursor                  mCursor;
+    private int                     mCount;
+    private String                  mLastWhereClause;
+    private String[]                mLastSelectionArgs;
+    private String                  mLastOrderBy;
+    private BrowserBookmarksPage    mBookmarksPage;
+    private ContentResolver         mContentResolver;
+    private ChangeObserver          mChangeObserver;
+    private DataSetObserver         mDataSetObserver;
+    private boolean                 mDataValid;
+
+    // When true, this adapter is used to pick a bookmark to create a shortcut
+    private boolean mCreateShortcut;
+    private int mExtraOffset;
+
+    // Implementation of WebIconDatabase.IconListener
+    private class IconReceiver implements IconListener {
+        public void onReceivedIcon(String url, Bitmap icon) {
+            updateBookmarkFavicon(mContentResolver, url, icon);
+        }
+    }
+
+    // Instance of IconReceiver
+    private final IconReceiver mIconReceiver = new IconReceiver();
+
+    /**
+     *  Create a new BrowserBookmarksAdapter.
+     *  @param b        BrowserBookmarksPage that instantiated this.  
+     *                  Necessary so it will adjust its focus
+     *                  appropriately after a search.
+     */
+    public BrowserBookmarksAdapter(BrowserBookmarksPage b, String curPage) {
+        this(b, curPage, false);
+    }
+
+    /**
+     *  Create a new BrowserBookmarksAdapter.
+     *  @param b        BrowserBookmarksPage that instantiated this.
+     *                  Necessary so it will adjust its focus
+     *                  appropriately after a search.
+     */
+    public BrowserBookmarksAdapter(BrowserBookmarksPage b, String curPage,
+            boolean createShortcut) {
+        mDataValid = false;
+        mCreateShortcut = createShortcut;
+        mExtraOffset = createShortcut ? 0 : 1;
+        mBookmarksPage = b;
+        mCurrentPage = b.getResources().getString(R.string.current_page) + 
+                curPage;
+        mContentResolver = b.getContentResolver();
+        mLastOrderBy = Browser.BookmarkColumns.CREATED + " DESC";
+        mChangeObserver = new ChangeObserver();
+        mDataSetObserver = new MyDataSetObserver();
+        // FIXME: Should have a default sort order that the user selects.
+        search(null);
+        // FIXME: This requires another query of the database after the
+        // initial search(null). Can we optimize this?
+        Browser.requestAllIcons(mContentResolver,
+                Browser.BookmarkColumns.FAVICON + " is NULL AND " +
+                Browser.BookmarkColumns.BOOKMARK + " == 1", mIconReceiver);
+    }
+    
+    /**
+     *  Return a hashmap with one row's Title, Url, and favicon.
+     *  @param position  Position in the list.
+     *  @return Bundle  Stores title, url of row position, favicon, and id
+     *                   for the url.  Return a blank map if position is out of
+     *                   range.
+     */
+    public Bundle getRow(int position) {
+        Bundle map = new Bundle();
+        if (position < mExtraOffset || position >= mCount) {
+            return map;
+        }
+        mCursor.moveToPosition(position- mExtraOffset);
+        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+        map.putString(Browser.BookmarkColumns.TITLE, 
+                mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
+        map.putString(Browser.BookmarkColumns.URL, url);
+        byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
+        if (data != null) {
+            map.putParcelable(Browser.BookmarkColumns.FAVICON,
+                    BitmapFactory.decodeByteArray(data, 0, data.length));
+        }
+        map.putInt("id", mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
+        return map;
+    }
+
+    /**
+     *  Update a row in the database with new information. 
+     *  Requeries the database if the information has changed.
+     *  @param map  Bundle storing id, title and url of new information
+     */
+    public void updateRow(Bundle map) {
+
+        // Find the record
+        int id = map.getInt("id");
+        int position = -1;
+        for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
+            if (mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX) == id) {
+                position = mCursor.getPosition();
+                break;
+            }
+        }
+        if (position < 0) {
+            return;
+        }
+
+        mCursor.moveToPosition(position);
+        ContentValues values = new ContentValues();
+        String title = map.getString(Browser.BookmarkColumns.TITLE);
+        if (!title.equals(mCursor
+                .getString(Browser.HISTORY_PROJECTION_TITLE_INDEX))) {
+            values.put(Browser.BookmarkColumns.TITLE, title);
+        }
+        String url = map.getString(Browser.BookmarkColumns.URL);
+        if (!url.equals(mCursor.
+                getString(Browser.HISTORY_PROJECTION_URL_INDEX))) {
+            values.put(Browser.BookmarkColumns.URL, url);
+        }
+        if (values.size() > 0
+                && mContentResolver.update(Browser.BOOKMARKS_URI, values,
+                        "_id = " + id, null) != -1) {
+            refreshList();
+        }
+    }
+
+    /**
+     *  Delete a row from the database.  Requeries the database.  
+     *  Does nothing if the provided position is out of range.
+     *  @param position Position in the list.
+     */
+    public void deleteRow(int position) {
+        if (position < mExtraOffset || position >= getCount()) {
+            return;
+        }
+        mCursor.moveToPosition(position- mExtraOffset);
+        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+        WebIconDatabase.getInstance().releaseIconForPageUrl(url);
+        Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI, mCursor
+                .getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
+        int numVisits = mCursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX);
+        if (0 == numVisits) {
+            mContentResolver.delete(uri, null, null);
+        } else {
+            // It is no longer a bookmark, but it is still a visited site.
+            ContentValues values = new ContentValues();
+            values.put(Browser.BookmarkColumns.BOOKMARK, 0);
+            mContentResolver.update(uri, values, null, null);
+        }
+        refreshList();
+    }
+    
+    /**
+     *  Delete all bookmarks from the db. Requeries the database.  
+     *  All bookmarks with become visited URLs or if never visited 
+     *  are removed
+     */
+    public void deleteAllRows() {
+        StringBuilder deleteIds = null;
+        StringBuilder convertIds = null;
+        
+        for (mCursor.moveToFirst(); !mCursor.isAfterLast(); mCursor.moveToNext()) {
+            String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+            WebIconDatabase.getInstance().releaseIconForPageUrl(url);
+            int id = mCursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX);
+            int numVisits = mCursor.getInt(Browser.HISTORY_PROJECTION_VISITS_INDEX);
+            if (0 == numVisits) {
+                if (deleteIds == null) {
+                    deleteIds = new StringBuilder();
+                    deleteIds.append("( ");
+                } else {
+                    deleteIds.append(" OR ( ");
+                }
+                deleteIds.append(BookmarkColumns._ID);
+                deleteIds.append(" = ");
+                deleteIds.append(id);
+                deleteIds.append(" )");
+            } else {
+                // It is no longer a bookmark, but it is still a visited site.
+                if (convertIds == null) {
+                    convertIds = new StringBuilder();
+                    convertIds.append("( ");
+                } else {
+                    convertIds.append(" OR ( ");
+                }
+                convertIds.append(BookmarkColumns._ID);
+                convertIds.append(" = ");
+                convertIds.append(id);
+                convertIds.append(" )");
+            }
+        }
+        
+        if (deleteIds != null) {
+            mContentResolver.delete(Browser.BOOKMARKS_URI, deleteIds.toString(), 
+                null);
+        }
+        if (convertIds != null) {
+            ContentValues values = new ContentValues();
+            values.put(Browser.BookmarkColumns.BOOKMARK, 0);
+            mContentResolver.update(Browser.BOOKMARKS_URI, values, 
+                    convertIds.toString(), null);
+        }
+        refreshList();
+    }
+
+    /**
+     *  Refresh list to recognize a change in the database.
+     */
+    public void refreshList() {
+        // FIXME: consider using requery().
+        // Need to do more work to get it to function though.
+        searchInternal(mLastWhereClause, mLastSelectionArgs, mLastOrderBy);
+    }
+
+    /**
+     *  Search the database for bookmarks that match the input string.
+     *  @param like String to use to search the database.  Strings with spaces 
+     *              are treated as having multiple search terms using the
+     *              OR operator.  Search both the title and url.
+     */
+    public void search(String like) {
+        String whereClause = Browser.BookmarkColumns.BOOKMARK + " == 1";
+        String[] selectionArgs = null;
+        if (like != null) {
+            String[] likes = like.split(" ");
+            int count = 0;
+            boolean firstTerm = true;
+            StringBuilder andClause = new StringBuilder(256);
+            for (int j = 0; j < likes.length; j++) {
+                if (likes[j].length() > 0) {
+                    if (firstTerm) {
+                        firstTerm = false;
+                    } else {
+                        andClause.append(" OR ");
+                    }
+                    andClause.append(Browser.BookmarkColumns.TITLE
+                            + " LIKE ? OR " + Browser.BookmarkColumns.URL
+                            + " LIKE ? ");
+                    count += 2;
+                }
+            }
+            if (count > 0) {
+                selectionArgs = new String[count];
+                count = 0;
+                for (int j = 0; j < likes.length; j++) {
+                    if (likes[j].length() > 0) {
+                        like = "%" + likes[j] + "%";
+                        selectionArgs[count++] = like;
+                        selectionArgs[count++] = like;
+                    }
+                }
+                whereClause += " AND (" + andClause + ")";
+            }
+        }
+        searchInternal(whereClause, selectionArgs, mLastOrderBy);
+    }
+
+    /**
+     * Update the bookmark's favicon.
+     * @param cr The ContentResolver to use.
+     * @param url The url of the bookmark to update.
+     * @param favicon The favicon bitmap to write to the db.
+     */
+    /* package */ static void updateBookmarkFavicon(ContentResolver cr,
+            String url, Bitmap favicon) {
+        if (url == null || favicon == null) {
+            return;
+        }
+        // Strip the query.
+        int query = url.indexOf('?');
+        String noQuery = url;
+        if (query != -1) {
+            noQuery = url.substring(0, query);
+        }
+        url = noQuery + '?';
+        // Use noQuery to search for the base url (i.e. if the url is
+        // http://www.yahoo.com/?rs=1, search for http://www.yahoo.com)
+        // Use url to match the base url with other queries (i.e. if the url is
+        // http://www.google.com/m, search for
+        // http://www.google.com/m?some_query)
+        final String[] selArgs = new String[] { noQuery, url };
+        final String where = "(" + Browser.BookmarkColumns.URL + " == ? OR "
+                + Browser.BookmarkColumns.URL + " GLOB ? || '*') AND "
+                + Browser.BookmarkColumns.BOOKMARK + " == 1";
+        final String[] projection = new String[] { Browser.BookmarkColumns._ID };
+        final Cursor c = cr.query(Browser.BOOKMARKS_URI, projection, where,
+                selArgs, null);
+        boolean succeed = c.moveToFirst();
+        ContentValues values = null;
+        while (succeed) {
+            if (values == null) {
+                final ByteArrayOutputStream os = new ByteArrayOutputStream();
+                favicon.compress(Bitmap.CompressFormat.PNG, 100, os);
+                values = new ContentValues();
+                values.put(Browser.BookmarkColumns.FAVICON, os.toByteArray());
+            }
+            cr.update(ContentUris.withAppendedId(Browser.BOOKMARKS_URI, c
+                    .getInt(0)), values, null, null);
+            succeed = c.moveToNext();
+        }
+        c.close();
+    }
+
+    /**
+     *  This sorts alphabetically, with non-capitalized titles before 
+     *  capitalized.
+     */
+    public void sortAlphabetical() {
+        searchInternal(mLastWhereClause, mLastSelectionArgs,
+                Browser.BookmarkColumns.TITLE + " COLLATE UNICODE ASC");
+    }
+
+    /**
+     *  Internal function used in search, sort, and refreshList.
+     */
+    private void searchInternal(String whereClause, String[] selectionArgs,
+            String orderBy) {
+        if (mCursor != null) {
+            mCursor.unregisterContentObserver(mChangeObserver);
+            mCursor.unregisterDataSetObserver(mDataSetObserver);
+            mBookmarksPage.stopManagingCursor(mCursor);
+            mCursor.deactivate();
+        }
+
+        mLastWhereClause = whereClause;
+        mLastSelectionArgs = selectionArgs;
+        mLastOrderBy = orderBy;
+        mCursor = mContentResolver.query(
+            Browser.BOOKMARKS_URI,
+            Browser.HISTORY_PROJECTION,
+            whereClause,
+            selectionArgs, 
+            orderBy);
+        mCursor.registerContentObserver(mChangeObserver);
+        mCursor.registerDataSetObserver(mDataSetObserver);
+        mBookmarksPage.startManagingCursor(mCursor);
+
+        mDataValid = true;
+        notifyDataSetChanged();
+
+        mCount = mCursor.getCount() + mExtraOffset;
+    }
+
+    /**
+     * How many items should be displayed in the list.
+     * @return Count of items.
+     */
+    public int getCount() {
+        if (mDataValid) {
+            return mCount;
+        } else {
+            return 0;
+        }
+    }
+
+    public boolean areAllItemsEnabled() {
+        return true;
+    }
+
+    public boolean isEnabled(int position) {
+        return true;
+    }
+
+    /**
+     * Get the data associated with the specified position in the list.
+     * @param position Index of the item whose data we want.
+     * @return The data at the specified position.
+     */
+    public Object getItem(int position) {
+        return null;
+    }
+
+    /**
+     * Get the row id associated with the specified position in the list.
+     * @param position Index of the item whose row id we want.
+     * @return The id of the item at the specified position.
+     */
+    public long getItemId(int position) {
+        return position;
+    }
+
+    /**
+     * Get a View that displays the data at the specified position
+     * in the list.
+     * @param position Index of the item whose view we want.
+     * @return A View corresponding to the data at the specified position.
+     */
+    public View getView(int position, View convertView, ViewGroup parent) {
+        if (!mDataValid) {
+            throw new IllegalStateException(
+                    "this should only be called when the cursor is valid");
+        }
+        if (position < 0 || position > mCount) {
+            throw new AssertionError(
+                    "BrowserBookmarksAdapter tried to get a view out of range");
+        }
+        if (position == 0 && !mCreateShortcut) {
+            AddNewBookmark b;
+            if (convertView instanceof AddNewBookmark) {
+                b = (AddNewBookmark) convertView;
+            } else {
+                b = new AddNewBookmark(mBookmarksPage);
+            }
+            b.setUrl(mCurrentPage);
+            return b;
+        }
+        if (convertView == null || convertView instanceof AddNewBookmark) {
+            convertView = new BookmarkItem(mBookmarksPage);
+        }
+        bind((BookmarkItem)convertView, position);
+        return convertView;
+    }
+
+    /**
+     *  Return the title for this item in the list.
+     */
+    public String getTitle(int position) {
+        return getString(Browser.HISTORY_PROJECTION_TITLE_INDEX, position);
+    }
+
+    /**
+     *  Return the Url for this item in the list.
+     */
+    public String getUrl(int position) {
+        return getString(Browser.HISTORY_PROJECTION_URL_INDEX, position);
+    }
+
+    /**
+     * Private helper function to return the title or url.
+     */
+    private String getString(int cursorIndex, int position) {
+        if (position < mExtraOffset || position > mCount) {
+            return "";
+        }
+        mCursor.moveToPosition(position- mExtraOffset);
+        return mCursor.getString(cursorIndex);
+    }
+
+    private void bind(BookmarkItem b, int position) {
+        mCursor.moveToPosition(position- mExtraOffset);
+
+        String title = mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX);
+        if (title.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
+            title = title.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+        }
+        b.setName(title);
+        String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+        if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
+            url = url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+        }
+        b.setUrl(url);
+        byte[] data = mCursor.getBlob(Browser.HISTORY_PROJECTION_FAVICON_INDEX);
+        if (data != null) {
+            b.setFavicon(BitmapFactory.decodeByteArray(data, 0, data.length));
+        } else {
+            b.setFavicon(null);
+        }
+    }
+
+    private class ChangeObserver extends ContentObserver {
+        public ChangeObserver() {
+            super(new Handler());
+        }
+
+        @Override
+        public boolean deliverSelfNotifications() {
+            return true;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            refreshList();
+        }
+    }
+    
+    private class MyDataSetObserver extends DataSetObserver {
+        @Override
+        public void onChanged() {
+            mDataValid = true;
+            notifyDataSetChanged();
+        }
+
+        @Override
+        public void onInvalidated() {
+            mDataValid = false;
+            notifyDataSetInvalidated();
+        }
+    }
+}
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
new file mode 100644
index 0000000..7708e8b
--- /dev/null
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -0,0 +1,385 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.os.ServiceManager;
+import android.provider.Browser;
+import android.text.IClipboard;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.ListView;
+
+/**
+ *  View showing the user's bookmarks in the browser.
+ */
+public class BrowserBookmarksPage extends Activity implements 
+        View.OnCreateContextMenuListener {
+
+    private BrowserBookmarksAdapter mBookmarksAdapter;
+    private static final int        BOOKMARKS_SAVE = 1;
+    private boolean                 mMaxTabsOpen;
+    private BookmarkItem            mContextHeader;
+    private AddNewBookmark          mAddHeader;
+    private boolean                 mCanceled = false;
+    private boolean                 mCreateShortcut;
+    // XXX: There is no public string defining this intent so if Home changes
+    // the value, we have to update this string.
+    private static final String     INSTALL_SHORTCUT =
+            "com.android.launcher.action.INSTALL_SHORTCUT";
+    
+    private final static String LOGTAG = "browser";
+
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        // It is possible that the view has been canceled when we get to
+        // this point as back has a higher priority 
+        if (mCanceled) {
+            return true;
+        }
+        AdapterView.AdapterContextMenuInfo i = 
+            (AdapterView.AdapterContextMenuInfo)item.getMenuInfo();
+        // If we have no menu info, we can't tell which item was selected.
+        if (i == null) {
+            return true;
+        }
+        
+        switch (item.getItemId()) {
+        case R.id.new_context_menu_id:
+            saveCurrentPage();
+            break;
+        case R.id.open_context_menu_id:
+            loadUrl(i.position);
+            break;
+        case R.id.edit_context_menu_id:
+            editBookmark(i.position);
+            break;
+        case R.id.shortcut_context_menu_id:
+            final Intent send = createShortcutIntent(getUrl(i.position),
+                    getBookmarkTitle(i.position));
+            send.setAction(INSTALL_SHORTCUT);
+            sendBroadcast(send);
+            break;
+        case R.id.delete_context_menu_id:
+            displayRemoveBookmarkDialog(i.position);
+            break;
+        case R.id.new_window_context_menu_id:
+            openInNewWindow(i.position);
+            break;
+        case R.id.send_context_menu_id:
+            Browser.sendString(BrowserBookmarksPage.this, getUrl(i.position));
+            break;
+        case R.id.copy_url_context_menu_id:
+            copy(getUrl(i.position));
+            
+        default:
+            return super.onContextItemSelected(item);
+        }
+        return true;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+                ContextMenuInfo menuInfo) {
+            AdapterView.AdapterContextMenuInfo i = 
+                    (AdapterView.AdapterContextMenuInfo) menuInfo;
+
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.bookmarkscontext, menu);
+
+            if (0 == i.position) {
+                menu.setGroupVisible(R.id.CONTEXT_MENU, false);
+                if (mAddHeader == null) {
+                    mAddHeader = new AddNewBookmark(BrowserBookmarksPage.this);
+                } else if (mAddHeader.getParent() != null) {
+                    ((ViewGroup) mAddHeader.getParent()).
+                            removeView(mAddHeader);
+                }
+                ((AddNewBookmark) i.targetView).copyTo(mAddHeader);
+                menu.setHeaderView(mAddHeader);
+                return;
+            }
+            menu.setGroupVisible(R.id.ADD_MENU, false);
+            BookmarkItem b = (BookmarkItem) i.targetView;
+            if (mContextHeader == null) {
+                mContextHeader = new BookmarkItem(BrowserBookmarksPage.this);
+            } else if (mContextHeader.getParent() != null) {
+                ((ViewGroup) mContextHeader.getParent()).
+                        removeView(mContextHeader);
+            }
+            b.copyTo(mContextHeader);
+            menu.setHeaderView(mContextHeader);
+
+            if (mMaxTabsOpen) {
+                menu.findItem(R.id.new_window_context_menu_id).setVisible(
+                        false);
+            }
+        }
+
+    /**
+     *  Create a new BrowserBookmarksPage.
+     */  
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+
+        setContentView(R.layout.browser_bookmarks_page);
+        setTitle(R.string.browser_bookmarks_page_bookmarks_text);
+
+        if (Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction())) {
+            mCreateShortcut = true;
+        }
+
+        mBookmarksAdapter = new BrowserBookmarksAdapter(this, 
+                getIntent().getStringExtra("url"), mCreateShortcut);
+        mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
+
+        ListView listView = (ListView) findViewById(R.id.list);
+        listView.setAdapter(mBookmarksAdapter);
+        listView.setDrawSelectorOnTop(false);
+        listView.setVerticalScrollBarEnabled(true);
+        listView.setOnItemClickListener(mListener);
+
+        if (!mCreateShortcut) {
+            listView.setOnCreateContextMenuListener(this);
+        }
+    }
+
+    private static final int SAVE_CURRENT_PAGE = 1000;
+    private final Handler mHandler = new Handler() {
+        @Override
+        public void handleMessage(Message msg) {
+            if (msg.what == SAVE_CURRENT_PAGE) {
+                saveCurrentPage();
+            }
+        }
+    };
+
+    private AdapterView.OnItemClickListener mListener = new AdapterView.OnItemClickListener() {
+        public void onItemClick(AdapterView parent, View v, int position, long id) {
+            // It is possible that the view has been canceled when we get to
+            // this point as back has a higher priority 
+            if (mCanceled) {
+                android.util.Log.e("browser", "item clicked when dismising");
+                return;
+            }
+            if (!mCreateShortcut) {
+                if (0 == position) {
+                    // XXX: Work-around for a framework issue.
+                    mHandler.sendEmptyMessage(SAVE_CURRENT_PAGE);
+                } else {
+                    loadUrl(position);
+                }
+            } else {
+                final Intent intent = createShortcutIntent(getUrl(position),
+                        getBookmarkTitle(position));
+                setResultToParent(RESULT_OK, intent);
+                finish();
+            }
+        }
+    };
+
+    private Intent createShortcutIntent(String url, String title) {
+        final Intent i = new Intent();
+        i.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW,
+                    Uri.parse(url)));
+        i.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
+        i.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+                Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this,
+                        R.drawable.ic_launcher_browser));
+        // Do not allow duplicate items
+        i.putExtra("duplicate", false);
+        return i;
+    }
+
+    private void saveCurrentPage() {
+        Intent i = new Intent(BrowserBookmarksPage.this,
+                AddBookmarkPage.class);
+        i.putExtras(getIntent());
+        startActivityForResult(i, BOOKMARKS_SAVE);
+    }
+
+    private void loadUrl(int position) {
+        Intent intent = (new Intent()).setAction(getUrl(position));
+        setResultToParent(RESULT_OK, intent);
+        finish();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        boolean result = super.onCreateOptionsMenu(menu);
+        if (!mCreateShortcut) {
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.bookmarks, menu);
+            return true;
+        }
+        return result;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.new_context_menu_id:
+                saveCurrentPage();
+                break;
+                
+            default:
+                return super.onOptionsItemSelected(item);
+        }
+        return true;
+    }
+
+    private void openInNewWindow(int position) {
+        Bundle b = new Bundle();
+        b.putBoolean("new_window", true);
+        setResultToParent(RESULT_OK,
+                (new Intent()).setAction(getUrl(position)).putExtras(b));
+
+        finish();
+    }
+    
+
+    private void editBookmark(int position) {
+        Intent intent = new Intent(BrowserBookmarksPage.this, 
+            AddBookmarkPage.class);
+        intent.putExtra("bookmark", getRow(position));
+        startActivityForResult(intent, BOOKMARKS_SAVE);
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+                                    Intent data) {
+        switch(requestCode) {
+            case BOOKMARKS_SAVE:
+                if (resultCode == RESULT_OK) {
+                    Bundle extras;
+                    if (data != null && (extras = data.getExtras()) != null) {
+                        // If there are extras, then we need to save
+                        // the edited bookmark. This is done in updateRow()
+                        String title = extras.getString("title");
+                        String url = extras.getString("url");
+                        if (title != null && url != null) {
+                            mBookmarksAdapter.updateRow(extras);
+                        }
+                    } else {
+                        // extras == null then a new bookmark was added to
+                        // the database.
+                        refreshList();
+                    }
+                }
+                break;
+            default:
+                break;
+        }
+    }
+    
+    private void displayRemoveBookmarkDialog(int position) {
+        // Put up a dialog asking if the user really wants to
+        // delete the bookmark
+        final int deletePos = position;
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.delete_bookmark)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setMessage(getText(R.string.delete_bookmark_warning).toString().replace(
+                        "%s", getBookmarkTitle(deletePos)))
+                .setPositiveButton(R.string.ok, 
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                deleteBookmark(deletePos);
+                            }
+                        })
+                .setNegativeButton(R.string.cancel, null)
+                .show();
+    }
+
+    /**
+     *  Refresh the shown list after the database has changed.
+     */
+    public void refreshList() {
+        mBookmarksAdapter.refreshList();
+    }
+    
+    /**
+     *  Return a hashmap representing the currently highlighted row.
+     */
+    public Bundle getRow(int position) {
+        return mBookmarksAdapter.getRow(position);
+    }
+
+    /**
+     *  Return the url of the currently highlighted row.
+     */
+    public String getUrl(int position) {
+        return mBookmarksAdapter.getUrl(position);
+    }
+
+    private void copy(CharSequence text) {
+        try {
+            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
+            if (clip != null) {
+                clip.setClipboardText(text);
+            }
+        } catch (android.os.RemoteException e) {
+            Log.e(LOGTAG, "Copy failed", e);
+        }
+    }
+    
+    public String getBookmarkTitle(int position) {
+        return mBookmarksAdapter.getTitle(position);
+    }
+
+    /**
+     *  Delete the currently highlighted row.
+     */
+    public void deleteBookmark(int position) {
+        mBookmarksAdapter.deleteRow(position);
+    }
+    
+    public boolean dispatchKeyEvent(KeyEvent event) {    
+        if (event.getKeyCode() ==  KeyEvent.KEYCODE_BACK && event.isDown()) {
+            setResultToParent(RESULT_CANCELED, null);
+            mCanceled = true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+    // that situation, we need to pass our result code up to our parent.
+    // However, if someone calls this Activity directly, then this has no
+    // parent, and it needs to set it on itself.
+    private void setResultToParent(int resultCode, Intent data) {
+        Activity a = getParent() == null ? this : getParent();
+        a.setResult(resultCode, data);
+    }
+}
diff --git a/src/com/android/browser/BrowserDownloadAdapter.java b/src/com/android/browser/BrowserDownloadAdapter.java
new file mode 100644
index 0000000..38b83fe
--- /dev/null
+++ b/src/com/android/browser/BrowserDownloadAdapter.java
@@ -0,0 +1,222 @@
+/*
+ * Copyright (C) 2007 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.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.drm.mobile1.DrmRawContent;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.provider.Downloads;
+import android.text.format.Formatter;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.ProgressBar;
+import android.widget.ResourceCursorAdapter;
+import android.widget.TextView;
+
+import java.io.File;
+import java.text.DateFormat;
+import java.util.Date;
+import java.util.List;
+
+/**
+ * This class is used to represent the data for the download list box. The only 
+ * real work done by this class is to construct a custom view for the line
+ * items.
+ */
+public class BrowserDownloadAdapter extends ResourceCursorAdapter {
+    
+    private int mFilenameColumnId;
+    private int mTitleColumnId;
+    private int mDescColumnId;
+    private int mStatusColumnId;
+    private int mTotalBytesColumnId;
+    private int mCurrentBytesColumnId;
+    private int mMimetypeColumnId;
+    private int mDateColumnId;
+
+    public BrowserDownloadAdapter(Context context, int layout, Cursor c) {
+        super(context, layout, c);
+        mFilenameColumnId = c.getColumnIndexOrThrow(Downloads._DATA);
+        mTitleColumnId = c.getColumnIndexOrThrow(Downloads.TITLE);
+        mDescColumnId = c.getColumnIndexOrThrow(Downloads.DESCRIPTION);
+        mStatusColumnId = c.getColumnIndexOrThrow(Downloads.STATUS);
+        mTotalBytesColumnId = c.getColumnIndexOrThrow(Downloads.TOTAL_BYTES);
+        mCurrentBytesColumnId = 
+            c.getColumnIndexOrThrow(Downloads.CURRENT_BYTES);
+        mMimetypeColumnId = c.getColumnIndexOrThrow(Downloads.MIMETYPE);
+        mDateColumnId = c.getColumnIndexOrThrow(Downloads.LAST_MODIFICATION);
+    }
+
+    @Override
+    public void bindView(View view, Context context, Cursor cursor) {
+        Resources r = context.getResources();
+        
+        // Retrieve the icon for this download
+        String mimeType = cursor.getString(mMimetypeColumnId);
+        ImageView iv = (ImageView) view.findViewById(R.id.download_icon);
+        if (DrmRawContent.DRM_MIMETYPE_MESSAGE_STRING.equalsIgnoreCase(mimeType)) {
+            iv.setImageResource(R.drawable.ic_launcher_drm_file);
+        } else if (mimeType == null) {
+            iv.setVisibility(View.INVISIBLE);
+        } else {
+            Intent intent = new Intent(Intent.ACTION_VIEW);
+            intent.setDataAndType(Uri.fromParts("file", "", null), mimeType);
+            PackageManager pm = context.getPackageManager();
+            List<ResolveInfo> list = pm.queryIntentActivities(intent,
+                    PackageManager.MATCH_DEFAULT_ONLY);
+            if (list.size() > 0) {
+                Drawable icon = list.get(0).activityInfo.loadIcon(pm);
+                iv.setImageDrawable(icon);
+                iv.setVisibility(View.VISIBLE);
+            } else {
+                iv.setVisibility(View.INVISIBLE);
+            }
+        }
+        
+        TextView tv = (TextView) view.findViewById(R.id.download_title);
+        String title = cursor.getString(mTitleColumnId);
+        if (title == null) {
+            String fullFilename = cursor.getString(mFilenameColumnId);
+            if (fullFilename == null) {
+                title = r.getString(R.string.download_unknown_filename);
+            } else {
+                // We have a filename, so we can build a title from that
+                title = new File(fullFilename).getName();
+                ContentValues values = new ContentValues();
+                values.put(Downloads.TITLE, title);
+                // assume "_id" is the first column for the cursor 
+                context.getContentResolver().update(
+                        ContentUris.withAppendedId(Downloads.CONTENT_URI,
+                        cursor.getLong(0)), values, null, null);
+            }
+        }
+        tv.setText(title);
+        
+        tv = (TextView) view.findViewById(R.id.domain);
+        tv.setText(cursor.getString(mDescColumnId));
+        
+        long totalBytes = cursor.getLong(mTotalBytesColumnId);
+        
+        int status = cursor.getInt(mStatusColumnId);
+        if (Downloads.isStatusCompleted(status)) { // Download stopped
+            View v = view.findViewById(R.id.progress_text);
+            v.setVisibility(View.GONE);
+
+            v = view.findViewById(R.id.download_progress);
+            v.setVisibility(View.GONE);
+
+            tv = (TextView) view.findViewById(R.id.complete_text);
+            tv.setVisibility(View.VISIBLE);
+            if (Downloads.isStatusError(status)) {
+                tv.setText(getErrorText(status));
+            } else {
+                tv.setText(r.getString(R.string.download_success, 
+                        Formatter.formatFileSize(mContext, totalBytes)));
+            }
+            
+            long time = cursor.getLong(mDateColumnId);
+            Date d = new Date(time);
+            DateFormat df = DateFormat.getDateInstance(DateFormat.SHORT);
+            tv = (TextView) view.findViewById(R.id.complete_date);
+            tv.setVisibility(View.VISIBLE);
+            tv.setText(df.format(d));
+            
+        } else { // Download is still running
+            tv = (TextView) view.findViewById(R.id.progress_text);
+            tv.setVisibility(View.VISIBLE);
+
+            View progress = view.findViewById(R.id.download_progress);
+            progress.setVisibility(View.VISIBLE);
+            
+            View v = view.findViewById(R.id.complete_date);
+            v.setVisibility(View.GONE);
+
+            v = view.findViewById(R.id.complete_text);
+            v.setVisibility(View.GONE);
+            
+            if (status == Downloads.STATUS_PENDING) {
+                tv.setText(r.getText(R.string.download_pending));
+            } else if (status == Downloads.STATUS_PENDING_PAUSED) {
+                tv.setText(r.getText(R.string.download_pending_network));
+            } else {
+                ProgressBar pb = (ProgressBar) progress;
+
+                StringBuilder sb = new StringBuilder();
+                if (status == Downloads.STATUS_RUNNING) {
+                    sb.append(r.getText(R.string.download_running));
+                } else {
+                    sb.append(r.getText(R.string.download_running_paused));
+                }
+                if (totalBytes > 0) {
+                    long currentBytes = cursor.getLong(mCurrentBytesColumnId); 
+                    int progressAmount = (int)(currentBytes * 100 / totalBytes);
+                    sb.append(' ');
+                    sb.append(progressAmount);
+                    sb.append("% (");
+                    sb.append(Formatter.formatFileSize(mContext, currentBytes));
+                    sb.append("/");
+                    sb.append(Formatter.formatFileSize(mContext, totalBytes));
+                    sb.append(")");
+                    pb.setIndeterminate(false);
+                    pb.setProgress(progressAmount);
+                } else {
+                    pb.setIndeterminate(true);
+                }
+                tv.setText(sb.toString()); 
+            }
+        }
+        
+    }
+    
+    /**
+     * Provide the resource id for the error string.
+     * @param status status of the download item
+     * @return resource id for the error string.
+     */
+    public static int getErrorText(int status) {
+        switch (status) {
+            case Downloads.STATUS_NOT_ACCEPTABLE:
+                return R.string.download_not_acceptable;
+                
+            case Downloads.STATUS_LENGTH_REQUIRED:
+                return R.string.download_length_required;
+                
+            case Downloads.STATUS_PRECONDITION_FAILED:
+                return R.string.download_precondition_failed;
+                
+            case Downloads.STATUS_CANCELED:
+                return R.string.download_canceled;
+
+            case Downloads.STATUS_FILE_ERROR:
+                return R.string.download_file_error;
+                
+            case Downloads.STATUS_BAD_REQUEST:
+            case Downloads.STATUS_UNKNOWN_ERROR:
+            default:
+                return R.string.download_error;
+        }
+    }
+}
diff --git a/src/com/android/browser/BrowserDownloadPage.java b/src/com/android/browser/BrowserDownloadPage.java
new file mode 100644
index 0000000..4397337
--- /dev/null
+++ b/src/com/android/browser/BrowserDownloadPage.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2007 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.app.Activity;
+import android.app.AlertDialog;
+import android.content.ActivityNotFoundException;
+import android.content.ContentValues;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.ContentUris;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.Downloads;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.MenuInflater;
+import android.view.View;
+import android.view.ViewGroup.LayoutParams;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.AdapterView.OnItemClickListener;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ *  View showing the user's current browser downloads
+ */
+public class BrowserDownloadPage extends Activity 
+        implements View.OnCreateContextMenuListener, OnItemClickListener {
+    
+    private ListView                mListView;
+    private Cursor                  mDownloadCursor;
+    private BrowserDownloadAdapter  mDownloadAdapter;
+    private int                     mStatusColumnId;
+    private int                     mIdColumnId;
+    private int                     mTitleColumnId;
+    private int                     mContextMenuPosition;
+    
+    @Override 
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setContentView(R.layout.browser_downloads_page);
+        
+        setTitle(getText(R.string.download_title));
+
+        mListView = (ListView) findViewById(R.id.list);
+        LayoutInflater factory = LayoutInflater.from(this);
+        View v = factory.inflate(R.layout.no_downloads, null);
+        addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.FILL_PARENT));
+        mListView.setEmptyView(v);
+        
+        mDownloadCursor = managedQuery(Downloads.CONTENT_URI, 
+                new String [] {"_id", Downloads.TITLE, Downloads.STATUS,
+                Downloads.TOTAL_BYTES, Downloads.CURRENT_BYTES, 
+                Downloads._DATA, Downloads.DESCRIPTION, 
+                Downloads.MIMETYPE, Downloads.LAST_MODIFICATION,
+                Downloads.VISIBILITY}, 
+                null, null);
+        
+        // only attach everything to the listbox if we can access
+        // the download database. Otherwise, just show it empty
+        if (mDownloadCursor != null) {
+            mStatusColumnId = 
+                    mDownloadCursor.getColumnIndexOrThrow(Downloads.STATUS);
+            mIdColumnId =
+                    mDownloadCursor.getColumnIndexOrThrow(Downloads._ID);
+            mTitleColumnId = 
+                    mDownloadCursor.getColumnIndexOrThrow(Downloads.TITLE);
+            
+            // Create a list "controller" for the data
+            mDownloadAdapter = new BrowserDownloadAdapter(this, 
+                    R.layout.browser_download_item, mDownloadCursor);
+            
+            mListView.setAdapter(mDownloadAdapter);
+            mListView.setScrollBarStyle(View.SCROLLBARS_INSIDE_INSET);
+            mListView.setOnCreateContextMenuListener(this);
+            mListView.setOnItemClickListener(this);
+            
+            Intent intent = getIntent();
+            if (intent != null && intent.getData() != null) {
+                int position = checkStatus(
+                        ContentUris.parseId(intent.getData()));
+                if (position >= 0) {
+                    mListView.setSelection(position);
+                }
+            }
+        }
+    }
+        
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        if (mDownloadCursor != null) {
+            MenuInflater inflater = getMenuInflater();
+            inflater.inflate(R.menu.downloadhistory, menu);
+        }
+        return true;
+    }
+    
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        boolean showCancel = getCancelableCount() > 0;
+        menu.findItem(R.id.download_menu_cancel_all).setEnabled(showCancel);
+        
+        boolean showClear = getClearableCount() > 0;
+        menu.findItem(R.id.download_menu_clear_all).setEnabled(showClear);
+        return super.onPrepareOptionsMenu(menu);
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.download_menu_cancel_all:
+                promptCancelAll();
+                return true;
+                
+            case R.id.download_menu_clear_all:
+                promptClearList();
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        mDownloadCursor.moveToPosition(mContextMenuPosition);
+        switch (item.getItemId()) {
+            case R.id.download_menu_open:
+                hideCompletedDownload();
+                openCurrentDownload();
+                return true;
+                
+            case R.id.download_menu_clear:
+            case R.id.download_menu_cancel:
+                getContentResolver().delete(
+                        ContentUris.withAppendedId(Downloads.CONTENT_URI,
+                        mDownloadCursor.getLong(mIdColumnId)), null, null);
+                return true;
+        }
+        return false;
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        if (mDownloadCursor != null) {
+            AdapterView.AdapterContextMenuInfo info = 
+                    (AdapterView.AdapterContextMenuInfo) menuInfo;
+            mDownloadCursor.moveToPosition(info.position);
+            mContextMenuPosition = info.position;
+            menu.setHeaderTitle(mDownloadCursor.getString(mTitleColumnId));
+            
+            MenuInflater inflater = getMenuInflater();
+            int status = mDownloadCursor.getInt(mStatusColumnId);
+            if (Downloads.isStatusSuccess(status)) {
+                inflater.inflate(R.menu.downloadhistorycontextfinished, menu);
+            } else if (Downloads.isStatusError(status)) {
+                inflater.inflate(R.menu.downloadhistorycontextfailed, menu);
+            } else {
+                inflater.inflate(R.menu.downloadhistorycontextrunning, menu);
+            }
+        }
+    }
+
+    /**
+     * This function is called to check the status of the download and if it
+     * has an error show an error dialog.
+     * @param id Row id of the download to check
+     * @return position of item
+     */
+    int checkStatus(final long id) {
+        int position = -1;
+        for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); 
+                mDownloadCursor.moveToNext()) {
+            if (id == mDownloadCursor.getLong(mIdColumnId)) {
+                position = mDownloadCursor.getPosition();
+                break;
+            }
+            
+        }
+        if (!mDownloadCursor.isAfterLast()) {
+            int status = mDownloadCursor.getInt(mStatusColumnId);
+            if (!Downloads.isStatusError(status)) {
+                return position;
+            }
+            
+            if (status == Downloads.STATUS_FILE_ERROR) {
+                String title = mDownloadCursor.getString(mTitleColumnId);
+                if (title == null || title.length() == 0) {
+                    title = getString(R.string.download_unknown_filename);
+                }
+                String msg = getString(R.string.download_file_error_dlg_msg, 
+                        title);
+                new AlertDialog.Builder(this)
+                        .setTitle(R.string.download_file_error_dlg_title)
+                        .setIcon(android.R.drawable.ic_popup_disk_full)
+                        .setMessage(msg)
+                        .setPositiveButton(R.string.ok, null)
+                        .setNegativeButton(R.string.retry, 
+                                new DialogInterface.OnClickListener() {
+                                    public void onClick(DialogInterface dialog, 
+                                            int whichButton) {
+                                        resumeDownload(id);
+                                    }
+                                })
+                        .show();
+            } else {
+                new AlertDialog.Builder(this)
+                        .setTitle(R.string.download_failed_generic_dlg_title)
+                        .setIcon(R.drawable.ssl_icon)
+                        .setMessage(BrowserDownloadAdapter.getErrorText(status))
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+            }
+        }
+        return position;
+    }
+    
+    /**
+     * Resume a given download
+     * @param id Row id of the download to resume
+     */
+    private void resumeDownload(final long id) {
+        // the relevant functionality doesn't exist in the download manager
+    }
+    
+    /**
+     * Prompt the user if they would like to clear the download history
+     */
+    private void promptClearList() {
+        new AlertDialog.Builder(this)
+               .setTitle(R.string.download_clear_dlg_title)
+               .setIcon(R.drawable.ssl_icon)
+               .setMessage(R.string.download_clear_dlg_msg)
+               .setPositiveButton(R.string.ok, 
+                       new DialogInterface.OnClickListener() {
+                           public void onClick(DialogInterface dialog, 
+                                   int whichButton) {
+                               clearAllDownloads();
+                           }
+                       })
+                .setNegativeButton(R.string.cancel, null)
+                .show();
+    }
+    
+    /**
+     * Return the number of items in the list that can be canceled.
+     * @return count
+     */
+    private int getCancelableCount() {
+        // Count the number of items that will be canceled.
+        int count = 0;
+        if (mDownloadCursor != null) {
+            for (mDownloadCursor.moveToFirst(); !mDownloadCursor.isAfterLast(); 
+                    mDownloadCursor.moveToNext()) {
+                int status = mDownloadCursor.getInt(mStatusColumnId);
+                if (!Downloads.isStatusCompleted(status)) {
+                    count++;
+                }
+            }
+        }
+        
+        return count;
+    }
+    
+    /**
+     * Prompt the user if they would like to clear the download history
+     */
+    private void promptCancelAll() {
+        int count = getCancelableCount();
+        
+        // If there is nothing to do, just return
+        if (count == 0) {
+            return;
+        }
+        
+        // Don't show the dialog if there is only one download
+        if (count == 1) {
+            cancelAllDownloads();
+            return;
+        }
+        String msg = 
+            getString(R.string.download_cancel_dlg_msg, count);
+        new AlertDialog.Builder(this)
+                .setTitle(R.string.download_cancel_dlg_title)
+                .setIcon(R.drawable.ssl_icon)
+                .setMessage(msg)
+                .setPositiveButton(R.string.ok, 
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, 
+                                    int whichButton) {
+                                cancelAllDownloads();
+                            }
+                        })
+                 .setNegativeButton(R.string.cancel, null)
+                 .show();
+    }
+    
+    /**
+     * Cancel all downloads. As canceled downloads are not
+     * listed, we removed them from the db. Removing a download
+     * record, cancels the download.
+     */
+    private void cancelAllDownloads() {
+        if (mDownloadCursor.moveToFirst()) {
+            StringBuilder where = new StringBuilder();
+            boolean firstTime = true;
+            while (!mDownloadCursor.isAfterLast()) {
+                int status = mDownloadCursor.getInt(mStatusColumnId);
+                if (!Downloads.isStatusCompleted(status)) {
+                    if (firstTime) {
+                        firstTime = false;
+                    } else {
+                        where.append(" OR ");
+                    }
+                    where.append("( ");
+                    where.append(Downloads._ID);
+                    where.append(" = '");
+                    where.append(mDownloadCursor.getLong(mIdColumnId));
+                    where.append("' )");
+                }
+                mDownloadCursor.moveToNext();
+            }
+            if (!firstTime) {
+                getContentResolver().delete(Downloads.CONTENT_URI,
+                        where.toString(), null);
+            }
+        }
+    }
+    
+    private int getClearableCount() {
+        int count = 0;
+        if (mDownloadCursor.moveToFirst()) {
+            while (!mDownloadCursor.isAfterLast()) {
+                int status = mDownloadCursor.getInt(mStatusColumnId);
+                if (Downloads.isStatusCompleted(status)) {
+                    count++;
+                }
+                mDownloadCursor.moveToNext();
+            }
+        }
+        return count;
+    }
+    
+    /**
+     * Clear all stopped downloads, ie canceled (though should not be
+     * there), error and success download items.
+     */
+    private void clearAllDownloads() {
+        if (mDownloadCursor.moveToFirst()) {
+            StringBuilder where = new StringBuilder();
+            boolean firstTime = true;
+            while (!mDownloadCursor.isAfterLast()) {
+                int status = mDownloadCursor.getInt(mStatusColumnId);
+                if (Downloads.isStatusCompleted(status)) {
+                    if (firstTime) {
+                        firstTime = false;
+                    } else {
+                        where.append(" OR ");
+                    }
+                    where.append("( ");
+                    where.append(Downloads._ID);
+                    where.append(" = '");
+                    where.append(mDownloadCursor.getLong(mIdColumnId));
+                    where.append("' )");
+                }
+                mDownloadCursor.moveToNext();
+            }
+            if (!firstTime) {
+                getContentResolver().delete(Downloads.CONTENT_URI,
+                        where.toString(), null);
+            }
+        }
+    }
+    
+    /**
+     * Open the content where the download db cursor currently is
+     */
+    private void openCurrentDownload() {
+        int filenameColumnId = 
+                mDownloadCursor.getColumnIndexOrThrow(Downloads._DATA);
+        String filename = mDownloadCursor.getString(filenameColumnId);
+        int mimetypeColumnId =
+                mDownloadCursor.getColumnIndexOrThrow(Downloads.MIMETYPE);
+        String mimetype = mDownloadCursor.getString(mimetypeColumnId);
+        Uri path = Uri.parse(filename);
+        // If there is no scheme, then it must be a file
+        if (path.getScheme() == null) {
+            path = Uri.fromFile(new File(filename));
+        }
+        Intent intent = new Intent(Intent.ACTION_VIEW);
+        intent.setDataAndType(path, mimetype);
+        intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
+        try {
+            startActivity(intent);
+        } catch (ActivityNotFoundException ex) {
+            new AlertDialog.Builder(this)
+                    .setTitle(R.string.download_failed_generic_dlg_title)
+                    .setIcon(R.drawable.ssl_icon)
+                    .setMessage(R.string.download_no_application)
+                    .setPositiveButton(R.string.ok, null)
+                    .show();
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
+     */
+    public void onItemClick(AdapterView parent, View view, int position, 
+            long id) {
+        // Open the selected item
+        mDownloadCursor.moveToPosition(position);
+        
+        hideCompletedDownload();
+
+        int status = mDownloadCursor.getInt(mStatusColumnId);
+        if (Downloads.isStatusSuccess(status)) {
+            // Open it if it downloaded successfully
+            openCurrentDownload();
+        } else {
+            // Check to see if there is an error.
+            checkStatus(id);
+        }
+    }
+    
+    /**
+     * hides the notification for the download pointed by mDownloadCursor
+     * if the download has completed.
+     */
+    private void hideCompletedDownload() {
+        int status = mDownloadCursor.getInt(mStatusColumnId);
+
+        int visibilityColumn = mDownloadCursor.getColumnIndexOrThrow(Downloads.VISIBILITY);
+        int visibility = mDownloadCursor.getInt(visibilityColumn);
+
+        if (Downloads.isStatusCompleted(status) &&
+                visibility == Downloads.VISIBILITY_VISIBLE_NOTIFY_COMPLETED) {
+            ContentValues values = new ContentValues();
+            values.put(Downloads.VISIBILITY, Downloads.VISIBILITY_VISIBLE);
+            getContentResolver().update(
+                    ContentUris.withAppendedId(Downloads.CONTENT_URI,
+                    mDownloadCursor.getLong(mIdColumnId)), values, null, null);
+        }
+    }
+}
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
new file mode 100644
index 0000000..42ca848
--- /dev/null
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2008 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.app.Activity;
+import android.app.ExpandableListActivity;
+import android.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.ServiceManager;
+import android.provider.Browser;
+import android.text.IClipboard;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.Menu;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.webkit.DateSorter;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.AdapterView;
+import android.widget.ExpandableListAdapter;
+import android.widget.ExpandableListView;
+import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
+import android.widget.TextView;
+
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * Activity for displaying the browser's history, divided into
+ * days of viewing.
+ */
+public class BrowserHistoryPage extends ExpandableListActivity {
+    private HistoryAdapter          mAdapter;
+    private DateSorter              mDateSorter;
+    private boolean                 mMaxTabsOpen;
+
+    private final static String LOGTAG = "browser";
+
+    // Implementation of WebIconDatabase.IconListener
+    private class IconReceiver implements IconListener {
+        public void onReceivedIcon(String url, Bitmap icon) {
+            setListAdapter(mAdapter);
+        }
+    }
+    // Instance of IconReceiver
+    private final IconReceiver mIconReceiver = new IconReceiver();
+
+    /**
+     * Report back to the calling activity to load a site.
+     * @param url   Site to load.
+     * @param newWindow True if the URL should be loaded in a new window
+     */
+    private void loadUrl(String url, boolean newWindow) {
+        Intent intent = new Intent().setAction(url);
+        if (newWindow) {
+            Bundle b = new Bundle();
+            b.putBoolean("new_window", true);
+            intent.putExtras(b);
+        }
+        setResultToParent(RESULT_OK, intent);
+        finish();
+    }
+    
+    private void copy(CharSequence text) {
+        try {
+            IClipboard clip = IClipboard.Stub.asInterface(ServiceManager.getService("clipboard"));
+            if (clip != null) {
+                clip.setClipboardText(text);
+            }
+        } catch (android.os.RemoteException e) {
+            Log.e(LOGTAG, "Copy failed", e);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        setTitle(R.string.browser_history);
+        
+        mDateSorter = new DateSorter(this);
+
+        mAdapter = new HistoryAdapter();
+        setListAdapter(mAdapter);
+        final ExpandableListView list = getExpandableListView();
+        list.setOnCreateContextMenuListener(this);
+        LayoutInflater factory = LayoutInflater.from(this);
+        View v = factory.inflate(R.layout.empty_history, null);
+        addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.FILL_PARENT));
+        list.setEmptyView(v);
+        // Do not post the runnable if there is nothing in the list.
+        if (list.getExpandableListAdapter().getGroupCount() > 0) {
+            list.post(new Runnable() {
+                public void run() {
+                    // In case the history gets cleared before this event
+                    // happens.
+                    if (list.getExpandableListAdapter().getGroupCount() > 0) {
+                        list.expandGroup(0);
+                    }
+                }
+            });
+        }
+        mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
+        CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
+                .addListener(mIconReceiver);
+        
+        // initialize the result to canceled, so that if the user just presses
+        // back then it will have the correct result
+        setResultToParent(RESULT_CANCELED, null);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.history, menu);
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        menu.findItem(R.id.clear_history_menu_id).setVisible(Browser.canClearHistory(this.getContentResolver()));
+        return true;
+    }
+    
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+            case R.id.clear_history_menu_id:
+                // FIXME: Need to clear the tab control in browserActivity 
+                // as well
+                Browser.clearHistory(getContentResolver());
+                mAdapter.refreshData();
+                return true;
+                
+            default:
+                break;
+        }  
+        return super.onOptionsItemSelected(item);
+    }
+    
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View v,
+            ContextMenuInfo menuInfo) {
+        ExpandableListContextMenuInfo i = 
+            (ExpandableListContextMenuInfo) menuInfo;
+        // Do not allow a context menu to come up from the group views.
+        if (!(i.targetView instanceof HistoryItem)) {
+            return;
+        }
+
+        // Inflate the menu
+        MenuInflater inflater = getMenuInflater();
+        inflater.inflate(R.menu.historycontext, menu);
+
+        // Setup the header
+        menu.setHeaderTitle(((HistoryItem)i.targetView).getUrl());
+
+        // Only show open in new tab if we have not maxed out available tabs
+        menu.findItem(R.id.new_window_context_menu_id).setVisible(!mMaxTabsOpen);
+        
+        // decide whether to show the share link option
+        PackageManager pm = getPackageManager();
+        Intent send = new Intent(Intent.ACTION_SEND);
+        send.setType("text/plain");
+        ResolveInfo ri = pm.resolveActivity(send, PackageManager.MATCH_DEFAULT_ONLY);
+        menu.findItem(R.id.share_link_context_menu_id).setVisible(ri != null);
+        
+        super.onCreateContextMenu(menu, v, menuInfo);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        ExpandableListContextMenuInfo i = 
+            (ExpandableListContextMenuInfo) item.getMenuInfo();
+        String url = ((HistoryItem)i.targetView).getUrl();
+        String title = ((HistoryItem)i.targetView).getName();
+        switch (item.getItemId()) {
+            case R.id.open_context_menu_id:
+                loadUrl(url, false);
+                return true;
+            case R.id.new_window_context_menu_id:
+                loadUrl(url, true);
+                return true;
+            case R.id.save_to_bookmarks_menu_id:
+                Browser.saveBookmark(this, title, url);
+                return true;
+            case R.id.share_link_context_menu_id:
+                Browser.sendString(this, url);
+                return true;
+            case R.id.copy_context_menu_id:
+                copy(url);
+                return true;
+            case R.id.delete_context_menu_id:
+                Browser.deleteFromHistory(getContentResolver(), url);
+                mAdapter.refreshData();
+                return true;
+            default:
+                break;
+        }
+        return super.onContextItemSelected(item);
+    }
+    
+    @Override
+    public boolean onChildClick(ExpandableListView parent, View v,
+            int groupPosition, int childPosition, long id) {
+        if (v instanceof HistoryItem) {
+            loadUrl(((HistoryItem) v).getUrl(), false);
+            return true;
+        }
+        return false;
+    }
+
+    // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+    // that situation, we need to pass our result code up to our parent.
+    // However, if someone calls this Activity directly, then this has no
+    // parent, and it needs to set it on itself.
+    private void setResultToParent(int resultCode, Intent data) {
+        Activity a = getParent() == null ? this : getParent();
+        a.setResult(resultCode, data);
+    }
+
+    private class ChangeObserver extends ContentObserver {
+        public ChangeObserver() {
+            super(new Handler());
+        }
+
+        @Override
+        public boolean deliverSelfNotifications() {
+            return true;
+        }
+
+        @Override
+        public void onChange(boolean selfChange) {
+            mAdapter.refreshData();
+        }
+    }
+    
+    private class HistoryAdapter implements ExpandableListAdapter {
+        
+        // Array for each of our bins.  Each entry represents how many items are
+        // in that bin.
+        int mItemMap[];
+        // This is our GroupCount.  We will have at most DateSorter.DAY_COUNT
+        // bins, less if the user has no items in one or more bins.
+        int mNumberOfBins;
+        Vector<DataSetObserver> mObservers;
+        Cursor mCursor;
+        
+        HistoryAdapter() {
+            mObservers = new Vector<DataSetObserver>();
+            
+            String whereClause = Browser.BookmarkColumns.VISITS + " > 0 ";
+            String orderBy = Browser.BookmarkColumns.DATE + " DESC";
+           
+            mCursor = managedQuery(
+                    Browser.BOOKMARKS_URI,
+                    Browser.HISTORY_PROJECTION,
+                    whereClause, null, orderBy);
+            
+            buildMap();
+            mCursor.registerContentObserver(new ChangeObserver());
+        }
+        
+        void refreshData() {
+            mCursor.requery();
+            buildMap();
+            for (DataSetObserver o : mObservers) {
+                o.onChanged();
+            }
+        }
+        
+        private void buildMap() {
+            // The cursor is sorted by date
+            // The ItemMap will store the number of items in each bin.
+            int array[] = new int[DateSorter.DAY_COUNT];
+            // Zero out the array.
+            for (int j = 0; j < DateSorter.DAY_COUNT; j++) {
+                array[j] = 0;
+            }
+            mNumberOfBins = 0;
+            int dateIndex = -1;
+            if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
+                while (!mCursor.isAfterLast()) {
+                    long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
+                    int index = mDateSorter.getIndex(date);
+                    if (index > dateIndex) {
+                        mNumberOfBins++;
+                        if (index == DateSorter.DAY_COUNT - 1) {
+                            // We are already in the last bin, so it will
+                            // include all the remaining items
+                            array[index] = mCursor.getCount()
+                                    - mCursor.getPosition();
+                            break;
+                        }
+                        dateIndex = index;
+                    }
+                    array[dateIndex]++;
+                    mCursor.moveToNext();
+                }
+            }
+            mItemMap = array;
+        }
+
+        // This translates from a group position in the Adapter to a position in
+        // our array.  This is necessary because some positions in the array
+        // have no history items, so we simply do not present those positions
+        // to the Adapter.
+        private int groupPositionToArrayPosition(int groupPosition) {
+            if (groupPosition < 0 || groupPosition >= DateSorter.DAY_COUNT) {
+                throw new AssertionError("group position out of range");
+            }
+            if (DateSorter.DAY_COUNT == mNumberOfBins || 0 == mNumberOfBins) {
+                // In the first case, we have exactly the same number of bins
+                // as our maximum possible, so there is no need to do a
+                // conversion
+                // The second statement is in case this method gets called when
+                // the array is empty, in which case the provided groupPosition
+                // will do fine.
+                return groupPosition;
+            }
+            int arrayPosition = -1;
+            while (groupPosition > -1) {
+                arrayPosition++;
+                if (mItemMap[arrayPosition] != 0) {
+                    groupPosition--;
+                }
+            }
+            return arrayPosition;
+        }
+
+        public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
+                View convertView, ViewGroup parent) {
+            groupPosition = groupPositionToArrayPosition(groupPosition);
+            HistoryItem item;
+            if (null == convertView || !(convertView instanceof HistoryItem)) {
+                item = new HistoryItem(BrowserHistoryPage.this);
+                // Add padding on the left so it will be indented from the
+                // arrows on the group views.
+                item.setPadding(item.getPaddingLeft() + 10,
+                        item.getPaddingTop(),
+                        item.getPaddingRight(),
+                        item.getPaddingBottom());
+            } else {
+                item = (HistoryItem) convertView;
+            }
+            int index = childPosition;
+            for (int i = 0; i < groupPosition; i++) {
+                index += mItemMap[i];
+            }
+            mCursor.moveToPosition(index);
+            item.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
+            String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+            item.setUrl(url);
+            item.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet(
+                    getContentResolver()).getFavicon(url));
+            item.setIsBookmark(1 ==
+                    mCursor.getInt(Browser.HISTORY_PROJECTION_BOOKMARK_INDEX));
+            return item;
+        }
+        
+        public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+            groupPosition = groupPositionToArrayPosition(groupPosition);
+            TextView item;
+            if (null == convertView || !(convertView instanceof TextView)) {
+                LayoutInflater factory = 
+                        LayoutInflater.from(BrowserHistoryPage.this);
+                item = (TextView) 
+                        factory.inflate(R.layout.history_header, null);
+            } else {
+                item = (TextView) convertView;
+            }
+            item.setText(mDateSorter.getLabel(groupPosition));
+            return item;
+        }
+
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        public boolean isChildSelectable(int groupPosition, int childPosition) {
+            return true;
+        }
+
+        public int getGroupCount() {
+            return mNumberOfBins;
+        }
+
+        public int getChildrenCount(int groupPosition) {
+            return mItemMap[groupPositionToArrayPosition(groupPosition)];
+        }
+
+        public Object getGroup(int groupPosition) {
+            return null;
+        }
+
+        public Object getChild(int groupPosition, int childPosition) {
+            return null;
+        }
+
+        public long getGroupId(int groupPosition) {
+            return groupPosition;
+        }
+
+        public long getChildId(int groupPosition, int childPosition) {
+            return (childPosition << 3) + groupPosition;
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        public void registerDataSetObserver(DataSetObserver observer) {
+            mObservers.add(observer);
+        }
+
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+            mObservers.remove(observer);
+        }
+
+        public void onGroupExpanded(int groupPosition) {
+        
+        }
+
+        public void onGroupCollapsed(int groupPosition) {
+        
+        }
+
+        public long getCombinedChildId(long groupId, long childId) {
+            return childId;
+        }
+
+        public long getCombinedGroupId(long groupId) {
+            return groupId;
+        }
+
+        public boolean isEmpty() {
+            return mCursor.getCount() == 0;
+        }
+    }
+}
diff --git a/src/com/android/browser/BrowserHomepagePreference.java b/src/com/android/browser/BrowserHomepagePreference.java
new file mode 100644
index 0000000..d4708c3
--- /dev/null
+++ b/src/com/android/browser/BrowserHomepagePreference.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2008 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.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.preference.EditTextPreference;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.util.Regex;
+import android.util.AttributeSet;
+
+public class BrowserHomepagePreference extends EditTextPreference implements
+        TextWatcher {
+
+    public BrowserHomepagePreference(Context context, AttributeSet attrs,
+            int defStyle) {
+        super(context, attrs, defStyle);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public BrowserHomepagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public BrowserHomepagePreference(Context context) {
+        super(context);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public void afterTextChanged(Editable s) {
+        AlertDialog dialog = (AlertDialog) getDialog();
+        // This callback is called before the dialog has been fully constructed
+        if (dialog != null) {
+            String url = s.toString();
+            dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(
+                    url.length() == 0 || url.equals("about:blank") ||
+                    Regex.WEB_URL_PATTERN.matcher(url).matches());
+        }
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int count,
+            int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+}
diff --git a/src/com/android/browser/BrowserPluginList.java b/src/com/android/browser/BrowserPluginList.java
new file mode 100644
index 0000000..6689b0e
--- /dev/null
+++ b/src/com/android/browser/BrowserPluginList.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2008 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.app.ListActivity;
+import android.os.Bundle;
+import android.view.View;
+import android.view.ViewGroup;
+import android.webkit.Plugin;
+import android.webkit.PluginList;
+import android.webkit.WebView;
+import android.widget.ArrayAdapter;
+import android.widget.LinearLayout;
+import android.widget.LinearLayout.LayoutParams;
+import android.widget.ListView;
+import android.widget.TextView;
+import java.util.ArrayList;
+import java.util.List;
+
+// Manages the list of installed (and loaded) plugins.
+public class BrowserPluginList extends ListActivity {
+    @Override
+    public void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        // The list of plugins can change under us, as the plugins are
+        // loaded and unloaded in a different thread. We make a copy
+        // of the list here.
+        List loadedPlugins = WebView.getPluginList().getList();
+        ArrayList localLoadedPluginList = new ArrayList();
+        synchronized (loadedPlugins) {
+            localLoadedPluginList.addAll(loadedPlugins);
+        }
+        setListAdapter(new ArrayAdapter(this,
+                                        android.R.layout.simple_list_item_1,
+                                        localLoadedPluginList));
+        setTitle(R.string.pref_plugin_installed);
+        // Add a text view to this ListActivity. This text view
+        // will be displayed when the list of plugins is empty.
+        TextView textView = new TextView(this);
+        textView.setId(android.R.id.empty);
+        textView.setText(R.string.pref_plugin_installed_empty_list);
+        addContentView(textView, new LinearLayout.LayoutParams(
+                               ViewGroup.LayoutParams.FILL_PARENT,
+                               ViewGroup.LayoutParams.WRAP_CONTENT));
+
+    }
+
+    @Override
+    public void onListItemClick(ListView l, View v, int position, long id) {
+        WebView.getPluginList().pluginClicked(this, position);
+    }
+}
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
new file mode 100644
index 0000000..5d6795b
--- /dev/null
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -0,0 +1,149 @@
+/*
+ * Copyright (C) 2008 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 java.util.List;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.preference.EditTextPreference;
+import android.preference.Preference;
+import android.preference.PreferenceActivity;
+import android.webkit.WebView;
+import android.webkit.Plugin;
+
+public class BrowserPreferencesPage extends PreferenceActivity
+        implements Preference.OnPreferenceChangeListener, 
+        Preference.OnPreferenceClickListener {
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        // Load the XML preferences file
+        addPreferencesFromResource(R.xml.browser_preferences);
+
+        Preference e = findPreference(BrowserSettings.PREF_HOMEPAGE);
+        e.setOnPreferenceChangeListener(this);
+        e.setSummary(getPreferenceScreen().getSharedPreferences()
+                .getString(BrowserSettings.PREF_HOMEPAGE, null));
+        
+        e = findPreference(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS);
+        e.setOnPreferenceChangeListener(this);
+        
+        e = findPreference(BrowserSettings.PREF_TEXT_SIZE);
+        e.setOnPreferenceChangeListener(this);
+        e.setSummary(getVisualTextSizeName(
+                getPreferenceScreen().getSharedPreferences()
+                .getString(BrowserSettings.PREF_TEXT_SIZE, null)) );
+        
+        e = findPreference(BrowserSettings.PREF_DEFAULT_TEXT_ENCODING);
+        e.setOnPreferenceChangeListener(this);
+        
+        if (BrowserSettings.getInstance().showDebugSettings()) {
+            addPreferencesFromResource(R.xml.debug_preferences);
+        }
+        
+        e = findPreference(BrowserSettings.PREF_GEARS_SETTINGS);
+        e.setOnPreferenceClickListener(this);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // sync the shared preferences back to BrowserSettings
+        BrowserSettings.getInstance().syncSharedPreferences(
+                getPreferenceScreen().getSharedPreferences());
+    }
+
+    public boolean onPreferenceChange(Preference pref, Object objValue) {
+        if (pref.getKey().equals(BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS)) {
+            Boolean value = (Boolean) objValue;
+            if (value.booleanValue() == true) {
+                finish();
+            }
+        } else if (pref.getKey().equals(BrowserSettings.PREF_HOMEPAGE)) {
+            String value = (String) objValue;
+            boolean needUpdate = value.indexOf(' ') != -1;
+            if (needUpdate) {
+                value = value.trim().replace(" ", "%20");
+            }
+            if (value.length() != 0 && Uri.parse(value).getScheme() == null) {
+                value = "http://" + value;
+                needUpdate = true;
+            }
+            // Set the summary value.
+            pref.setSummary(value);
+            if (needUpdate) {
+                // Update through the EditText control as it has a cached copy
+                // of the string and it will handle persisting the value
+                ((EditTextPreference) pref).setText(value);
+
+                // as we update the value above, we need to return false
+                // here so that setText() is not called by EditTextPref
+                // with the old value.
+                return false;
+            } else {
+                return true;
+            }
+        } else if (pref.getKey().equals(BrowserSettings.PREF_TEXT_SIZE)) {
+            pref.setSummary(getVisualTextSizeName((String) objValue));
+            return true;
+        } else if (pref.getKey().equals(
+                BrowserSettings.PREF_DEFAULT_TEXT_ENCODING)) {
+            pref.setSummary((String) objValue);
+            return true;
+        }
+        
+        return false;
+    }
+    
+    public boolean onPreferenceClick(Preference pref) {
+        if (pref.getKey().equals(BrowserSettings.PREF_GEARS_SETTINGS)) {
+            List<Plugin> loadedPlugins = WebView.getPluginList().getList();
+            for(Plugin p : loadedPlugins) {
+                if (p.getName().equals("gears")) {
+                    p.dispatchClickEvent(this);
+                    return true;
+                }
+            }
+            
+        }
+        return true;
+    }
+    
+    private CharSequence getVisualTextSizeName(String enumName) {
+        CharSequence[] visualNames = 
+                getResources().getTextArray(R.array.pref_text_size_choices);
+        CharSequence[] enumNames = 
+                getResources().getTextArray(R.array.pref_text_size_values);
+        
+        // Sanity check
+        if (visualNames.length != enumNames.length) {
+            return "";
+        }
+        
+        for (int i = 0; i < enumNames.length; i++) {
+            if (enumNames[i].equals(enumName)) {
+                return visualNames[i];
+            }
+        }
+        
+        return "";
+    }
+}
diff --git a/src/com/android/browser/BrowserProvider.java b/src/com/android/browser/BrowserProvider.java
new file mode 100644
index 0000000..0c930c6
--- /dev/null
+++ b/src/com/android/browser/BrowserProvider.java
@@ -0,0 +1,654 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.ISearchManager;
+import android.app.SearchManager;
+import android.content.ComponentName;
+import android.content.ContentProvider;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.content.UriMatcher;
+import android.database.AbstractCursor;
+import android.database.Cursor;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.os.RemoteException;
+import android.os.ServiceManager;
+import android.os.SystemProperties;
+import android.provider.Browser;
+import android.util.Log;
+import android.server.search.SearchableInfo;
+import android.text.util.Regex;
+
+public class BrowserProvider extends ContentProvider {
+
+    private SQLiteOpenHelper mOpenHelper;
+    private static final String sDatabaseName = "browser.db";
+    private static final String TAG = "BrowserProvider";
+    private static final String ORDER_BY = "visits DESC, date DESC";
+
+    private static final String[] TABLE_NAMES = new String[] {
+        "bookmarks", "searches"
+    };
+    private static final String[] SUGGEST_PROJECTION = new String[] {
+            "_id", "url", "title", "bookmark"
+    };
+    private static final String SUGGEST_SELECTION = 
+            "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?";
+    private String[] SUGGEST_ARGS = new String[4];
+
+    // shared suggestion array index, make sure to match COLUMNS
+    private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1;
+    private static final int SUGGEST_COLUMN_INTENT_DATA_ID = 2;
+    private static final int SUGGEST_COLUMN_TEXT_1_ID = 3;
+    private static final int SUGGEST_COLUMN_TEXT_2_ID = 4;
+    private static final int SUGGEST_COLUMN_ICON_1_ID = 5;
+    private static final int SUGGEST_COLUMN_ICON_2_ID = 6;
+    private static final int SUGGEST_COLUMN_QUERY_ID = 7;
+
+    // shared suggestion columns
+    private static final String[] COLUMNS = new String[] {
+            "_id",
+            SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
+            SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+            SearchManager.SUGGEST_COLUMN_TEXT_1,
+            SearchManager.SUGGEST_COLUMN_TEXT_2,
+            SearchManager.SUGGEST_COLUMN_ICON_1,
+            SearchManager.SUGGEST_COLUMN_ICON_2,
+            SearchManager.SUGGEST_COLUMN_QUERY};
+
+    private static final int MAX_SUGGESTION_SHORT_ENTRIES = 3;
+    private static final int MAX_SUGGESTION_LONG_ENTRIES = 6;
+
+    // make sure that these match the index of TABLE_NAMES
+    private static final int URI_MATCH_BOOKMARKS = 0;
+    private static final int URI_MATCH_SEARCHES = 1;
+    // (id % 10) should match the table name index
+    private static final int URI_MATCH_BOOKMARKS_ID = 10;
+    private static final int URI_MATCH_SEARCHES_ID = 11;
+    //
+    private static final int URI_MATCH_SUGGEST = 20;
+
+    private static final UriMatcher URI_MATCHER;
+
+    static {
+        URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
+        URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_BOOKMARKS],
+                URI_MATCH_BOOKMARKS);
+        URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_BOOKMARKS] + "/#",
+                URI_MATCH_BOOKMARKS_ID);
+        URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_SEARCHES],
+                URI_MATCH_SEARCHES);
+        URI_MATCHER.addURI("browser", TABLE_NAMES[URI_MATCH_SEARCHES] + "/#",
+                URI_MATCH_SEARCHES_ID);
+        URI_MATCHER.addURI("browser", SearchManager.SUGGEST_URI_PATH_QUERY,
+                URI_MATCH_SUGGEST);
+    }
+
+    // 1 -> 2 add cache table
+    // 2 -> 3 update history table
+    // 3 -> 4 add passwords table
+    // 4 -> 5 add settings table
+    // 5 -> 6 ?
+    // 6 -> 7 ?
+    // 7 -> 8 drop proxy table
+    // 8 -> 9 drop settings table
+    // 9 -> 10 add form_urls and form_data
+    // 10 -> 11 add searches table
+    // 11 -> 12 modify cache table
+    // 12 -> 13 modify cache table
+    // 13 -> 14 correspond with Google Bookmarks schema
+    // 14 -> 15 move couple of tables to either browser private database or webview database
+    // 15 -> 17 Set it up for the SearchManager
+    // 17 -> 18 Added favicon in bookmarks table for Home shortcuts
+    // 18 -> 19 Remove labels table
+    private static final int DATABASE_VERSION = 19;
+
+    public BrowserProvider() {
+    }
+  
+
+    private static CharSequence replaceSystemPropertyInString(CharSequence srcString) {
+        StringBuffer sb = new StringBuffer();
+        int lastCharLoc = 0;
+        for (int i = 0; i < srcString.length(); ++i) {
+            char c = srcString.charAt(i);
+            if (c == '{') {
+                sb.append(srcString.subSequence(lastCharLoc, i));
+                lastCharLoc = i;
+          inner:
+                for (int j = i; j < srcString.length(); ++j) {
+                    char k = srcString.charAt(j);
+                    if (k == '}') {
+                        String propertyKeyValue = srcString.subSequence(i + 1, j).toString();
+                        // See if the propertyKeyValue specifies a default value
+                        int defaultOffset = propertyKeyValue.indexOf(':');
+                        if (defaultOffset == -1) {
+                            sb.append(SystemProperties.get(propertyKeyValue));
+                        } else {
+                            String propertyKey = propertyKeyValue.substring(0, defaultOffset);
+                            String defaultValue = 
+                                    propertyKeyValue.substring(defaultOffset + 1, 
+                                                               propertyKeyValue.length());
+                            sb.append(SystemProperties.get(propertyKey, defaultValue));
+                        }
+                        lastCharLoc = j + 1;
+                        i = j;
+                        break inner;
+                    }
+                }
+            }
+        }
+        if (srcString.length() - lastCharLoc > 0) {
+            // Put on the tail, if there is one
+            sb.append(srcString.subSequence(lastCharLoc, srcString.length()));
+        }
+        return sb;
+    }
+
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+        private Context mContext;
+
+        public DatabaseHelper(Context context) {
+            super(context, sDatabaseName, null, DATABASE_VERSION);
+            mContext = context;
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            db.execSQL("CREATE TABLE bookmarks (" +
+                    "_id INTEGER PRIMARY KEY," +
+                    "title TEXT," +
+                    "url TEXT," +
+                    "visits INTEGER," +
+                    "date LONG," +
+                    "created LONG," +
+                    "description TEXT," +
+                    "bookmark INTEGER," +
+                    "favicon BLOB DEFAULT NULL" +
+                    ");");
+
+            final CharSequence[] bookmarks = mContext.getResources()
+                    .getTextArray(R.array.bookmarks);
+            int size = bookmarks.length;
+            try {
+                for (int i = 0; i < size; i = i + 2) {
+                    CharSequence bookmarkDestination = replaceSystemPropertyInString(bookmarks[i + 1]);
+                    db.execSQL("INSERT INTO bookmarks (title, url, visits, " +
+                            "date, created, bookmark)" + " VALUES('" +
+                            bookmarks[i] + "', '" + bookmarkDestination + 
+                            "', 0, 0, 0, 1);");
+                }
+            } catch (ArrayIndexOutOfBoundsException e) {
+            }
+
+            db.execSQL("CREATE TABLE searches (" +
+                    "_id INTEGER PRIMARY KEY," +
+                    "search TEXT," +
+                    "date LONG" +
+                    ");");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                    + newVersion + ", which will destroy all old data");
+            if (oldVersion == 18) {
+                db.execSQL("DROP TABLE IF EXISTS labels");
+            } else {
+                db.execSQL("DROP TABLE IF EXISTS bookmarks");
+                db.execSQL("DROP TABLE IF EXISTS searches");
+                onCreate(db);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    /*
+     * Subclass AbstractCursor so we can combine multiple Cursors and add
+     * "Google Search".
+     * Here are the rules.
+     * 1. We only have MAX_SUGGESTION_LONG_ENTRIES in the list plus 
+     *      "Google Search";
+     * 2. If bookmark/history entries are less than 
+     *      (MAX_SUGGESTION_SHORT_ENTRIES -1), we include Google suggest.
+     */
+    private class MySuggestionCursor extends AbstractCursor {
+        private Cursor  mHistoryCursor;
+        private Cursor  mSuggestCursor;
+        private int     mHistoryCount;
+        private int     mSuggestionCount;
+        private boolean mBeyondCursor;
+        private String  mString;
+
+        public MySuggestionCursor(Cursor hc, Cursor sc, String string) {
+            mHistoryCursor = hc;
+            mSuggestCursor = sc;
+            mHistoryCount = hc.getCount();
+            mSuggestionCount = sc != null ? sc.getCount() : 0;
+            if (mSuggestionCount > (MAX_SUGGESTION_LONG_ENTRIES - mHistoryCount)) {
+                mSuggestionCount = MAX_SUGGESTION_LONG_ENTRIES - mHistoryCount;
+            }
+            mString = string;
+            mBeyondCursor = false;
+        }
+
+        @Override
+        public boolean onMove(int oldPosition, int newPosition) {
+            if (mHistoryCursor == null) {
+                return false;
+            }
+            if (mHistoryCount > newPosition) {
+                mHistoryCursor.moveToPosition(newPosition);
+                mBeyondCursor = false;
+            } else if (mHistoryCount + mSuggestionCount > newPosition) {
+                mSuggestCursor.moveToPosition(newPosition - mHistoryCount);
+                mBeyondCursor = false;
+            } else {
+                mBeyondCursor = true;
+            }
+            return true;
+        }
+
+        @Override
+        public int getCount() {
+            if (mString.length() > 0) {
+                return mHistoryCount + mSuggestionCount + 1;
+            } else {
+                return mHistoryCount + mSuggestionCount;
+            }
+        }
+
+        @Override
+        public String[] getColumnNames() {
+            return COLUMNS;
+        }
+
+        @Override
+        public String getString(int columnIndex) {
+            if ((mPos != -1 && mHistoryCursor != null)) {
+                switch(columnIndex) {
+                    case SUGGEST_COLUMN_INTENT_ACTION_ID:
+                        if (mHistoryCount > mPos) {
+                            return Intent.ACTION_VIEW;
+                        } else {
+                            return Intent.ACTION_SEARCH;
+                        }
+
+                    case SUGGEST_COLUMN_INTENT_DATA_ID:
+                        if (mHistoryCount > mPos) {
+                            return mHistoryCursor.getString(1);
+                        } else {
+                            return null;
+                        }
+
+                    case SUGGEST_COLUMN_TEXT_1_ID:
+                        if (mHistoryCount > mPos) {
+                            return mHistoryCursor.getString(1);
+                        } else if (!mBeyondCursor) {
+                            return mSuggestCursor.getString(1);
+                        } else {
+                            return mString;
+                        }
+
+                    case SUGGEST_COLUMN_TEXT_2_ID:
+                        if (mHistoryCount > mPos) {
+                            return mHistoryCursor.getString(2);
+                        } else if (!mBeyondCursor) {
+                            return mSuggestCursor.getString(2);
+                        } else {
+                            return getContext().getString(R.string.search_google);
+                        }
+
+                    case SUGGEST_COLUMN_ICON_1_ID:
+                        if (mHistoryCount > mPos) {
+                            if (mHistoryCursor.getInt(3) == 1) {
+                                return new Integer(
+                                        R.drawable.ic_search_category_bookmark)
+                                        .toString();
+                            } else {
+                                return new Integer(
+                                        R.drawable.ic_search_category_history)
+                                        .toString();
+                            }
+                        } else {
+                            return new Integer(
+                                    R.drawable.ic_search_category_suggest)
+                                    .toString();
+                        }
+
+                    case SUGGEST_COLUMN_ICON_2_ID:
+                        return new String("0");
+
+                    case SUGGEST_COLUMN_QUERY_ID:
+                        if (mHistoryCount > mPos) {
+                            return null;
+                        } else if (!mBeyondCursor) {
+                            return mSuggestCursor.getString(3);
+                        } else {
+                            return mString;
+                        }
+                }
+            }
+            return null;
+        }
+
+        @Override
+        public double getDouble(int column) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public float getFloat(int column) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public int getInt(int column) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public long getLong(int column) {
+            if ((mPos != -1) && column == 0) {
+                return mPos;        // use row# as the _Id
+            }
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public short getShort(int column) {
+            throw new UnsupportedOperationException();
+        }
+
+        @Override
+        public boolean isNull(int column) {
+            throw new UnsupportedOperationException();
+        }
+
+        // TODO Temporary change, finalize after jq's changes go in
+        public void deactivate() {
+            if (mHistoryCursor != null) {
+                mHistoryCursor.deactivate();
+            }
+            if (mSuggestCursor != null) {
+                mSuggestCursor.deactivate();
+            }
+            super.deactivate();
+        }
+
+        public boolean requery() {
+            return (mHistoryCursor != null ? mHistoryCursor.requery() : false) |
+                    (mSuggestCursor != null ? mSuggestCursor.requery() : false);
+        }
+
+        // TODO Temporary change, finalize after jq's changes go in
+        public void close() {
+            super.close();
+            if (mHistoryCursor != null) {
+                mHistoryCursor.close();
+                mHistoryCursor = null;
+            }
+            if (mSuggestCursor != null) {
+                mSuggestCursor.close();
+                mSuggestCursor = null;
+            }
+        }
+    }
+
+    @Override
+    public Cursor query(Uri url, String[] projectionIn, String selection,
+            String[] selectionArgs, String sortOrder) 
+            throws IllegalStateException {
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+
+        int match = URI_MATCHER.match(url);
+        if (match == -1) {
+            throw new IllegalArgumentException("Unknown URL");
+        }
+
+        if (match == URI_MATCH_SUGGEST) {
+            String suggestSelection;
+            String [] myArgs;
+            if (selectionArgs[0] == null || selectionArgs[0].equals("")) {
+                suggestSelection = null;
+                myArgs = null;
+            } else {
+                String like = selectionArgs[0] + "%";
+                if (selectionArgs[0].startsWith("http")) {
+                    myArgs = new String[1];
+                    myArgs[0] = like;
+                    suggestSelection = selection;
+                } else {
+                    SUGGEST_ARGS[0] = "http://" + like;
+                    SUGGEST_ARGS[1] = "http://www." + like;
+                    SUGGEST_ARGS[2] = "https://" + like;
+                    SUGGEST_ARGS[3] = "https://www." + like;
+                    myArgs = SUGGEST_ARGS;
+                    suggestSelection = SUGGEST_SELECTION;
+                }
+            }
+
+            Cursor c = db.query(TABLE_NAMES[URI_MATCH_BOOKMARKS],
+                    SUGGEST_PROJECTION, suggestSelection, myArgs, null, null,
+                    ORDER_BY,
+                    (new Integer(MAX_SUGGESTION_LONG_ENTRIES)).toString());
+
+            if (Regex.WEB_URL_PATTERN.matcher(selectionArgs[0]).matches()) {
+                return new MySuggestionCursor(c, null, "");
+            } else {
+                // get Google suggest if there is still space in the list
+                if (myArgs != null && myArgs.length > 1
+                        && c.getCount() < (MAX_SUGGESTION_SHORT_ENTRIES - 1)) {
+                    ISearchManager sm = ISearchManager.Stub
+                            .asInterface(ServiceManager
+                                    .getService(Context.SEARCH_SERVICE));
+                    SearchableInfo si = null;
+                    try {
+                        // use the global search to get Google suggest provider
+                        si = sm.getSearchableInfo(new ComponentName(
+                                getContext(), "com.android.browser"), true);
+
+                        // similar to the getSuggestions() in SearchDialog.java
+                        StringBuilder uriStr = new StringBuilder("content://");
+                        uriStr.append(si.getSuggestAuthority());
+                        // if content path provided, insert it now
+                        final String contentPath = si.getSuggestPath();
+                        if (contentPath != null) {
+                            uriStr.append('/');
+                            uriStr.append(contentPath);
+                        }
+                        // append standard suggestion query path 
+                        uriStr.append('/' + SearchManager.SUGGEST_URI_PATH_QUERY);
+                        // inject query, either as selection args or inline
+                        String[] selArgs = null;
+                        if (si.getSuggestSelection() != null) {
+                            selArgs = new String[] {selectionArgs[0]};
+                        } else {
+                            uriStr.append('/');
+                            uriStr.append(Uri.encode(selectionArgs[0]));
+                        }
+
+                        // finally, make the query
+                        Cursor sc = getContext().getContentResolver().query(
+                                Uri.parse(uriStr.toString()), null,
+                                si.getSuggestSelection(), selArgs, null);
+
+                        return new MySuggestionCursor(c, sc, selectionArgs[0]);
+                    } catch (RemoteException e) {
+                    }
+                }
+                return new MySuggestionCursor(c, null, selectionArgs[0]);
+            }
+        }
+
+        String[] projection = null;
+        if (projectionIn != null && projectionIn.length > 0) {
+            projection = new String[projectionIn.length + 1];
+            System.arraycopy(projectionIn, 0, projection, 0, projectionIn.length);
+            projection[projectionIn.length] = "_id AS _id";
+        }
+
+        StringBuilder whereClause = new StringBuilder(256);
+        if (match == URI_MATCH_BOOKMARKS_ID || match == URI_MATCH_SEARCHES_ID) {
+            whereClause.append("(_id = ").append(url.getPathSegments().get(1))
+                    .append(")");
+        }
+
+        // Tack on the user's selection, if present
+        if (selection != null && selection.length() > 0) {
+            if (whereClause.length() > 0) {
+                whereClause.append(" AND ");
+            }
+
+            whereClause.append('(');
+            whereClause.append(selection);
+            whereClause.append(')');
+        }
+        Cursor c = db.query(TABLE_NAMES[match % 10], projection,
+                whereClause.toString(), selectionArgs, null, null, sortOrder,
+                null);
+        c.setNotificationUri(getContext().getContentResolver(), url);
+        return c;
+    }
+
+    @Override
+    public String getType(Uri url) {
+        int match = URI_MATCHER.match(url);
+        switch (match) {
+            case URI_MATCH_BOOKMARKS:
+                return "vnd.android.cursor.dir/bookmark";
+
+            case URI_MATCH_BOOKMARKS_ID:
+                return "vnd.android.cursor.item/bookmark";
+
+            case URI_MATCH_SEARCHES:
+                return "vnd.android.cursor.dir/searches";
+
+            case URI_MATCH_SEARCHES_ID:
+                return "vnd.android.cursor.item/searches";
+
+            case URI_MATCH_SUGGEST:
+                return SearchManager.SUGGEST_MIME_TYPE;
+
+            default:
+                throw new IllegalArgumentException("Unknown URL");
+        }
+    }
+
+    @Override
+    public Uri insert(Uri url, ContentValues initialValues) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        int match = URI_MATCHER.match(url);
+        Uri uri = null;
+        switch (match) {
+            case URI_MATCH_BOOKMARKS: {
+                // Insert into the bookmarks table
+                long rowID = db.insert(TABLE_NAMES[URI_MATCH_BOOKMARKS], "url",
+                        initialValues);
+                if (rowID > 0) {
+                    uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
+                            rowID);
+                }
+                break;
+            }
+
+            case URI_MATCH_SEARCHES: {
+                // Insert into the searches table
+                long rowID = db.insert(TABLE_NAMES[URI_MATCH_SEARCHES], "url",
+                        initialValues);
+                if (rowID > 0) {
+                    uri = ContentUris.withAppendedId(Browser.SEARCHES_URI,
+                            rowID);
+                }
+                break;
+            }
+
+            default:
+                throw new IllegalArgumentException("Unknown URL");
+        }
+
+        if (uri == null) {
+            throw new IllegalArgumentException("Unknown URL");
+        }
+        getContext().getContentResolver().notifyChange(uri, null);
+        return uri;
+    }
+
+    @Override
+    public int delete(Uri url, String where, String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        int match = URI_MATCHER.match(url);
+        if (match == -1 || match == URI_MATCH_SUGGEST) {
+            throw new IllegalArgumentException("Unknown URL");
+        }
+
+        if (match == URI_MATCH_BOOKMARKS_ID || match == URI_MATCH_SEARCHES_ID) {
+            StringBuilder sb = new StringBuilder();
+            if (where != null && where.length() > 0) {
+                sb.append("( ");
+                sb.append(where);
+                sb.append(" ) AND ");
+            }
+            sb.append("_id = ");
+            sb.append(url.getPathSegments().get(1));
+            where = sb.toString();
+        }
+
+        int count = db.delete(TABLE_NAMES[match % 10], where, whereArgs);
+        getContext().getContentResolver().notifyChange(url, null);
+        return count;
+    }
+
+    @Override
+    public int update(Uri url, ContentValues values, String where,
+            String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+
+        int match = URI_MATCHER.match(url);
+        if (match == -1 || match == URI_MATCH_SUGGEST) {
+            throw new IllegalArgumentException("Unknown URL");
+        }
+
+        if (match == URI_MATCH_BOOKMARKS_ID || match == URI_MATCH_SEARCHES_ID) {
+            StringBuilder sb = new StringBuilder();
+            if (where != null && where.length() > 0) {
+                sb.append("( ");
+                sb.append(where);
+                sb.append(" ) AND ");
+            }
+            sb.append("_id = ");
+            sb.append(url.getPathSegments().get(1));
+            where = sb.toString();
+        }
+
+        int ret = db.update(TABLE_NAMES[match % 10], values, where, whereArgs);
+        getContext().getContentResolver().notifyChange(url, null);
+        return ret;
+    }
+}
diff --git a/src/com/android/browser/BrowserSearchpagePreference.java b/src/com/android/browser/BrowserSearchpagePreference.java
new file mode 100644
index 0000000..09e8993
--- /dev/null
+++ b/src/com/android/browser/BrowserSearchpagePreference.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2008 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.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.preference.EditTextPreference;
+import android.text.Editable;
+import android.text.TextWatcher;
+import android.text.util.Regex;
+import android.util.AttributeSet;
+
+public class BrowserSearchpagePreference extends EditTextPreference implements
+        TextWatcher {
+
+    public BrowserSearchpagePreference(Context context, AttributeSet attrs,
+            int defStyle) {
+        super(context, attrs, defStyle);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public BrowserSearchpagePreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public BrowserSearchpagePreference(Context context) {
+        super(context);
+        getEditText().addTextChangedListener(this);
+    }
+
+    public void afterTextChanged(Editable s) {
+        AlertDialog dialog = (AlertDialog) getDialog();
+        // This callback is called before the dialog has been fully constructed
+        if (dialog != null) {
+            String string = s.toString();
+            int length = string.length();
+            int first = length > 0 ? string
+                    .indexOf(BrowserActivity.QUERY_PLACE_HOLDER) : -1;
+            int last = length > 0 ? string
+                    .lastIndexOf(BrowserActivity.QUERY_PLACE_HOLDER) : -1;
+            dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(
+                    length == 0 || (first > 0 && first == last));
+        }
+    }
+
+    public void beforeTextChanged(CharSequence s, int start, int count,
+            int after) {
+    }
+
+    public void onTextChanged(CharSequence s, int start, int before, int count) {
+    }
+}
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
new file mode 100644
index 0000000..d8c5186
--- /dev/null
+++ b/src/com/android/browser/BrowserSettings.java
@@ -0,0 +1,442 @@
+/*
+ * Copyright (C) 2007 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.app.Activity;
+import android.content.ContentResolver;
+import android.content.Context;
+import android.content.pm.ActivityInfo;
+import android.content.SharedPreferences;
+import android.content.SharedPreferences.Editor;
+import android.os.SystemProperties;
+import android.view.WindowManager;
+import android.webkit.CacheManager;
+import android.webkit.CookieManager;
+import android.webkit.WebView;
+import android.webkit.WebViewDatabase;
+import android.webkit.WebIconDatabase;
+import android.webkit.WebSettings;
+import android.preference.PreferenceManager;
+import android.provider.Browser;
+
+import java.util.HashMap;
+import java.util.Observable;
+
+/*
+ * Package level class for storing various WebView and Browser settings. To use
+ * this class:
+ * BrowserSettings s = BrowserSettings.getInstance();
+ * s.addObserver(webView.getSettings());
+ * s.loadFromDb(context); // Only needed on app startup
+ * s.javaScriptEnabled = true;
+ * ... // set any other settings
+ * s.update(); // this will update all the observers
+ *
+ * To remove an observer:
+ * s.deleteObserver(webView.getSettings());
+ */
+class BrowserSettings extends Observable {
+
+    // Public variables for settings
+    // NOTE: these defaults need to be kept in sync with the XML
+    // until the performance of PreferenceManager.setDefaultValues()
+    // is improved.
+    private boolean loadsImagesAutomatically = true;
+    private boolean javaScriptEnabled = true;
+    private boolean pluginsEnabled = true;
+    private String pluginsPath;  // default value set in loadFromDb().
+    private boolean javaScriptCanOpenWindowsAutomatically = false;
+    private boolean showSecurityWarnings = true;
+    private boolean rememberPasswords = true;
+    private boolean saveFormData = true;
+    private boolean openInBackground = false;
+    private String defaultTextEncodingName;
+    private String homeUrl = "http://www.google.com/m?client=ms-" +
+        SystemProperties.get("persist.sys.com.google.clientid", "unknown");
+    private boolean loginInitialized = false;
+    private boolean autoFitPage = true;
+    private boolean showDebugSettings = false;
+
+    // Development settings
+    public WebSettings.LayoutAlgorithm layoutAlgorithm =
+        WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
+    private boolean useWideViewPort = true;
+    private int userAgent = 0;
+    private boolean tracing = false;
+    private boolean lightTouch = false;
+    private boolean navDump = false;
+    // Browser only settings
+    private boolean doFlick = false;
+
+    // Private preconfigured values
+    private static int minimumFontSize = 8;
+    private static int minimumLogicalFontSize = 8;
+    private static int defaultFontSize = 16;
+    private static int defaultFixedFontSize = 13;
+    private static WebSettings.TextSize textSize =
+        WebSettings.TextSize.NORMAL;
+
+    // Preference keys that are used outside this class
+    public final static String PREF_CLEAR_CACHE = "privacy_clear_cache";
+    public final static String PREF_CLEAR_COOKIES = "privacy_clear_cookies";
+    public final static String PREF_CLEAR_HISTORY = "privacy_clear_history";
+    public final static String PREF_HOMEPAGE = "homepage";
+    public final static String PREF_CLEAR_FORM_DATA =
+            "privacy_clear_form_data";
+    public final static String PREF_CLEAR_PASSWORDS =
+            "privacy_clear_passwords";
+    public final static String PREF_EXTRAS_RESET_DEFAULTS =
+            "reset_default_preferences";
+    public final static String PREF_DEBUG_SETTINGS = "debug_menu";
+    public final static String PREF_GEARS_SETTINGS = "gears_settings";
+    public final static String PREF_TEXT_SIZE = "text_size";
+    public final static String PREF_DEFAULT_TEXT_ENCODING =
+            "default_text_encoding";
+
+    private static final String DESKTOP_USERAGENT = "Mozilla/5.0 (Macintosh; " +
+            "U; Intel Mac OS X 10_5_5; en-us) AppleWebKit/525.18 (KHTML, " +
+            "like Gecko) Version/3.1.2 Safari/525.20.1";
+
+    private static final String IPHONE_USERAGENT = "Mozilla/5.0 (iPhone; U; " +
+            "CPU iPhone OS 2_2 like Mac OS X; en-us) AppleWebKit/525.18.1 " +
+            "(KHTML, like Gecko) Version/3.1.1 Mobile/5G77 Safari/525.20";
+
+    // Value to truncate strings when adding them to a TextView within
+    // a ListView
+    public final static int MAX_TEXTVIEW_LEN = 80;
+
+    private TabControl mTabControl;
+
+    // Single instance of the BrowserSettings for use in the Browser app.
+    private static BrowserSettings sSingleton;
+
+    // Private map of WebSettings to Observer objects used when deleting an
+    // observer.
+    private HashMap<WebSettings,Observer> mWebSettingsToObservers =
+        new HashMap<WebSettings,Observer>();
+
+    /*
+     * An observer wrapper for updating a WebSettings object with the new
+     * settings after a call to BrowserSettings.update().
+     */
+    static class Observer implements java.util.Observer {
+        // Private WebSettings object that will be updated.
+        private WebSettings mSettings;
+
+        Observer(WebSettings w) {
+            mSettings = w;
+        }
+
+        public void update(Observable o, Object arg) {
+            BrowserSettings b = (BrowserSettings)o;
+            WebSettings s = mSettings;
+
+            s.setLayoutAlgorithm(b.layoutAlgorithm);
+            if (b.userAgent == 0) {
+                // use the default ua string
+                s.setUserAgentString(null);
+            } else if (b.userAgent == 1) {
+                s.setUserAgentString(DESKTOP_USERAGENT);
+            } else if (b.userAgent == 2) {
+                s.setUserAgentString(IPHONE_USERAGENT);
+            }
+            s.setUseWideViewPort(b.useWideViewPort);
+            s.setLoadsImagesAutomatically(b.loadsImagesAutomatically);
+            s.setJavaScriptEnabled(b.javaScriptEnabled);
+            s.setPluginsEnabled(b.pluginsEnabled);
+            s.setPluginsPath(b.pluginsPath);
+            s.setJavaScriptCanOpenWindowsAutomatically(
+                    b.javaScriptCanOpenWindowsAutomatically);
+            s.setDefaultTextEncodingName(b.defaultTextEncodingName);
+            s.setMinimumFontSize(b.minimumFontSize);
+            s.setMinimumLogicalFontSize(b.minimumLogicalFontSize);
+            s.setDefaultFontSize(b.defaultFontSize);
+            s.setDefaultFixedFontSize(b.defaultFixedFontSize);
+            s.setNavDump(b.navDump);
+            s.setTextSize(b.textSize);
+            s.setLightTouchEnabled(b.lightTouch);
+            s.setSaveFormData(b.saveFormData);
+            s.setSavePassword(b.rememberPasswords);
+
+            // WebView inside Browser doesn't want initial focus to be set.
+            s.setNeedInitialFocus(false);
+            // Browser supports multiple windows
+            s.setSupportMultipleWindows(true);
+            // Turn off file access
+            s.setAllowFileAccess(false);
+        }
+    }
+
+    /**
+     * Load settings from the browser app's database.
+     * NOTE: Strings used for the preferences must match those specified
+     * in the browser_preferences.xml
+     * @param ctx A Context object used to query the browser's settings
+     *            database. If the database exists, the saved settings will be
+     *            stored in this BrowserSettings object. This will update all
+     *            observers of this object.
+     */
+    public void loadFromDb(Context ctx) {
+        SharedPreferences p =
+                PreferenceManager.getDefaultSharedPreferences(ctx);
+
+        // Set the default value for the plugins path to the application's
+        // local directory.
+        pluginsPath = ctx.getDir("plugins", 0).getPath();
+
+        // Load the defaults from the xml
+        // This call is TOO SLOW, need to manually keep the defaults
+        // in sync
+        //PreferenceManager.setDefaultValues(ctx, R.xml.browser_preferences);
+        syncSharedPreferences(p);
+    }
+
+    /* package */ void syncSharedPreferences(SharedPreferences p) {
+        homeUrl =
+            p.getString(PREF_HOMEPAGE, homeUrl);
+        loadsImagesAutomatically = p.getBoolean("load_images",
+                loadsImagesAutomatically);
+        javaScriptEnabled = p.getBoolean("enable_javascript",
+                javaScriptEnabled);
+        pluginsEnabled = p.getBoolean("enable_plugins",
+                pluginsEnabled);
+        pluginsPath = p.getString("plugins_path", pluginsPath);
+        javaScriptCanOpenWindowsAutomatically = !p.getBoolean(
+            "block_popup_windows",
+            !javaScriptCanOpenWindowsAutomatically);
+        showSecurityWarnings = p.getBoolean("show_security_warnings",
+                showSecurityWarnings);
+        rememberPasswords = p.getBoolean("remember_passwords",
+                rememberPasswords);
+        saveFormData = p.getBoolean("save_formdata",
+                saveFormData);
+        boolean accept_cookies = p.getBoolean("accept_cookies",
+                CookieManager.getInstance().acceptCookie());
+        CookieManager.getInstance().setAcceptCookie(accept_cookies);
+        openInBackground = p.getBoolean("open_in_background", openInBackground);
+        loginInitialized = p.getBoolean("login_initialized", loginInitialized);
+        textSize = WebSettings.TextSize.valueOf(
+                p.getString(PREF_TEXT_SIZE, textSize.name()));
+        autoFitPage = p.getBoolean("autofit_pages", autoFitPage);
+        useWideViewPort = true; // use wide view port for either setting
+        if (autoFitPage) {
+            layoutAlgorithm = WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
+        } else {
+            layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
+        }
+        defaultTextEncodingName =
+                p.getString(PREF_DEFAULT_TEXT_ENCODING,
+                        defaultTextEncodingName);
+
+        showDebugSettings =
+                p.getBoolean(PREF_DEBUG_SETTINGS, showDebugSettings);
+        // Debug menu items have precidence if the menu is visible
+        if (showDebugSettings) {
+            boolean small_screen = p.getBoolean("small_screen",
+                    layoutAlgorithm ==
+                    WebSettings.LayoutAlgorithm.SINGLE_COLUMN);
+            if (small_screen) {
+                layoutAlgorithm = WebSettings.LayoutAlgorithm.SINGLE_COLUMN;
+            } else {
+                boolean normal_layout = p.getBoolean("normal_layout",
+                        layoutAlgorithm == WebSettings.LayoutAlgorithm.NORMAL);
+                if (normal_layout) {
+                    layoutAlgorithm = WebSettings.LayoutAlgorithm.NORMAL;
+                } else {
+                    layoutAlgorithm =
+                            WebSettings.LayoutAlgorithm.NARROW_COLUMNS;
+                }
+            }
+            useWideViewPort = p.getBoolean("wide_viewport", useWideViewPort);
+            tracing = p.getBoolean("enable_tracing", tracing);
+            lightTouch = p.getBoolean("enable_light_touch", lightTouch);
+            navDump = p.getBoolean("enable_nav_dump", navDump);
+            doFlick = p.getBoolean("enable_flick", doFlick);
+            userAgent = Integer.parseInt(p.getString("user_agent", "0"));
+            mTabControl.getBrowserActivity().setBaseSearchUrl(
+                    p.getString("search_url", ""));
+        }
+        update();
+    }
+
+    public String getPluginsPath() {
+        return pluginsPath;
+    }
+
+    public String getHomePage() {
+        return homeUrl;
+    }
+
+    public void setHomePage(Context context, String url) {
+        Editor ed = PreferenceManager.
+                getDefaultSharedPreferences(context).edit();
+        ed.putString(PREF_HOMEPAGE, url);
+        ed.commit();
+        homeUrl = url;
+    }
+
+    public boolean isLoginInitialized() {
+        return loginInitialized;
+    }
+
+    public void setLoginInitialized(Context context) {
+        loginInitialized = true;
+        Editor ed = PreferenceManager.
+                getDefaultSharedPreferences(context).edit();
+        ed.putBoolean("login_initialized", loginInitialized);
+        ed.commit();
+    }
+
+    public WebSettings.TextSize getTextSize() {
+        return textSize;
+    }
+
+    public boolean openInBackground() {
+        return openInBackground;
+    }
+
+    public boolean showSecurityWarnings() {
+        return showSecurityWarnings;
+    }
+
+    public boolean isTracing() {
+        return tracing;
+    }
+
+    public boolean isLightTouch() {
+        return lightTouch;
+    }
+
+    public boolean isNavDump() {
+        return navDump;
+    }
+
+    public boolean doFlick() {
+        return doFlick;
+    }
+
+    public boolean showDebugSettings() {
+        return showDebugSettings;
+    }
+
+    public void toggleDebugSettings() {
+        showDebugSettings = !showDebugSettings;
+        navDump = showDebugSettings;
+        update();
+    }
+
+    /**
+     * Add a WebSettings object to the list of observers that will be updated
+     * when update() is called.
+     *
+     * @param s A WebSettings object that is strictly tied to the life of a
+     *            WebView.
+     */
+    public Observer addObserver(WebSettings s) {
+        Observer old = mWebSettingsToObservers.get(s);
+        if (old != null) {
+            super.deleteObserver(old);
+        }
+        Observer o = new Observer(s);
+        mWebSettingsToObservers.put(s, o);
+        super.addObserver(o);
+        return o;
+    }
+
+    /**
+     * Delete the given WebSettings observer from the list of observers.
+     * @param s The WebSettings object to be deleted.
+     */
+    public void deleteObserver(WebSettings s) {
+        Observer o = mWebSettingsToObservers.get(s);
+        if (o != null) {
+            mWebSettingsToObservers.remove(s);
+            super.deleteObserver(o);
+        }
+    }
+
+    /*
+     * Package level method for obtaining a single app instance of the
+     * BrowserSettings.
+     */
+    /*package*/ static BrowserSettings getInstance() {
+        if (sSingleton == null ) {
+            sSingleton = new BrowserSettings();
+        }
+        return sSingleton;
+    }
+
+    /*
+     * Package level method for associating the BrowserSettings with TabControl
+     */
+    /* package */void setTabControl(TabControl tabControl) {
+        mTabControl = tabControl;
+    }
+
+    /*
+     * Update all the observers of the object.
+     */
+    /*package*/ void update() {
+        setChanged();
+        notifyObservers();
+    }
+
+    /*package*/ void clearCache(Context context) {
+        WebIconDatabase.getInstance().removeAllIcons();
+        if (mTabControl != null) {
+            WebView current = mTabControl.getCurrentWebView();
+            if (current != null) {
+                current.clearCache(true);
+            }
+        }
+    }
+
+    /*package*/ void clearCookies(Context context) {
+        CookieManager.getInstance().removeAllCookie();
+    }
+
+    /* package */void clearHistory(Context context) {
+        ContentResolver resolver = context.getContentResolver();
+        Browser.clearHistory(resolver);
+        Browser.clearSearches(resolver);
+    }
+
+    /* package */ void clearFormData(Context context) {
+        WebViewDatabase.getInstance(context).clearFormData();
+        if (mTabControl != null) {
+            mTabControl.getCurrentTopWebView().clearFormData();
+        }
+    }
+
+    /*package*/ void clearPasswords(Context context) {
+        WebViewDatabase db = WebViewDatabase.getInstance(context);
+        db.clearUsernamePassword();
+        db.clearHttpAuthUsernamePassword();
+    }
+
+    /*package*/ void resetDefaultPreferences(Context context) {
+        SharedPreferences p =
+            PreferenceManager.getDefaultSharedPreferences(context);
+        p.edit().clear().commit();
+        PreferenceManager.setDefaultValues(context, R.xml.browser_preferences,
+                true);
+    }
+
+    // Private constructor that does nothing.
+    private BrowserSettings() {
+    }
+}
diff --git a/src/com/android/browser/BrowserYesNoPreference.java b/src/com/android/browser/BrowserYesNoPreference.java
new file mode 100644
index 0000000..65cde71
--- /dev/null
+++ b/src/com/android/browser/BrowserYesNoPreference.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2008 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 com.android.internal.preference.YesNoPreference;
+
+import android.content.Context;
+import android.util.AttributeSet;
+
+class BrowserYesNoPreference extends YesNoPreference {
+
+    // This is the constructor called by the inflater
+    public BrowserYesNoPreference(Context context, AttributeSet attrs) {
+        super(context, attrs);
+    }
+
+    @Override
+    protected void onDialogClosed(boolean positiveResult) {
+        super.onDialogClosed(positiveResult);
+
+        if (positiveResult) {
+            setEnabled(false);
+
+            Context context = getContext();
+            if (BrowserSettings.PREF_CLEAR_CACHE.equals(getKey())) {
+                BrowserSettings.getInstance().clearCache(context);
+            } else if (BrowserSettings.PREF_CLEAR_COOKIES.equals(getKey())) {
+                BrowserSettings.getInstance().clearCookies(context);
+            } else if (BrowserSettings.PREF_CLEAR_HISTORY.equals(getKey())) {
+                BrowserSettings.getInstance().clearHistory(context);
+            } else if (BrowserSettings.PREF_CLEAR_FORM_DATA.equals(getKey())) {
+                BrowserSettings.getInstance().clearFormData(context);
+            } else if (BrowserSettings.PREF_CLEAR_PASSWORDS.equals(getKey())) {
+                BrowserSettings.getInstance().clearPasswords(context);
+            } else if (BrowserSettings.PREF_EXTRAS_RESET_DEFAULTS.equals(
+                    getKey())) {
+                BrowserSettings.getInstance().resetDefaultPreferences(context);
+                setEnabled(true);
+            }
+        }
+    }
+}
diff --git a/src/com/android/browser/CombinedBookmarkHistoryActivity.java b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
new file mode 100644
index 0000000..963f179
--- /dev/null
+++ b/src/com/android/browser/CombinedBookmarkHistoryActivity.java
@@ -0,0 +1,124 @@
+/*
+ * 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;
+
+import android.app.Activity;
+import android.app.TabActivity;
+import android.content.ContentResolver;
+import android.content.Intent;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.provider.Browser;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.TabHost;
+import android.widget.TabHost.TabSpec;
+import android.view.Window;
+
+import java.util.HashMap;
+import java.util.Vector;
+
+public class CombinedBookmarkHistoryActivity extends TabActivity
+        implements TabHost.OnTabChangeListener {
+    /* package */ static String BOOKMARKS_TAB = "bookmark";
+    /* package */ static String VISITED_TAB = "visited";
+    /* package */ static String HISTORY_TAB = "history";
+    /* package */ static String STARTING_TAB = "tab";
+
+    static class IconListenerSet implements IconListener {
+        // Used to store favicons as we get them from the database
+        // FIXME: We use a different method to get the Favicons in
+        // BrowserBookmarksAdapter. They should probably be unified.
+        private HashMap<String, Bitmap> mUrlsToIcons;
+        private Vector<IconListener> mListeners;
+
+        public IconListenerSet() {
+            mUrlsToIcons = new HashMap<String, Bitmap>();
+            mListeners = new Vector<IconListener>();
+        }
+        public void onReceivedIcon(String url, Bitmap icon) {
+            mUrlsToIcons.put(url, icon);
+            for (IconListener listener : mListeners) {
+                listener.onReceivedIcon(url, icon);
+            }
+        }
+        public void addListener(IconListener listener) {
+            mListeners.add(listener);
+        }
+        public Bitmap getFavicon(String url) {
+            return (Bitmap) mUrlsToIcons.get(url);
+        }
+    }
+    private static IconListenerSet sIconListenerSet;
+    static IconListenerSet getIconListenerSet(ContentResolver cr) {
+        if (null == sIconListenerSet) {
+            sIconListenerSet = new IconListenerSet();
+            Browser.requestAllIcons(cr, null, sIconListenerSet);
+        }
+        return sIconListenerSet;
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+        setContentView(R.layout.tabs);
+        TabHost tabHost = getTabHost();
+        tabHost.setOnTabChangedListener(this);
+
+        Bundle extras = getIntent().getExtras();
+        Resources resources = getResources();
+
+        getIconListenerSet(getContentResolver());
+        Intent bookmarksIntent = new Intent(this, BrowserBookmarksPage.class);
+        bookmarksIntent.putExtras(extras);
+        tabHost.addTab(tabHost.newTabSpec(BOOKMARKS_TAB)
+                .setIndicator(resources.getString(R.string.tab_bookmarks),
+                resources.getDrawable(R.drawable.browser_bookmark_tab))
+                .setContent(bookmarksIntent));
+
+        Intent visitedIntent = new Intent(this, MostVisitedActivity.class);
+        visitedIntent.putExtras(extras);
+        tabHost.addTab(tabHost.newTabSpec(VISITED_TAB)
+                .setIndicator(resources.getString(R.string.tab_most_visited),
+                resources.getDrawable(R.drawable.browser_visited_tab))
+                .setContent(visitedIntent));
+
+        Intent historyIntent = new Intent(this, BrowserHistoryPage.class);
+        historyIntent.putExtras(extras);
+        tabHost.addTab(tabHost.newTabSpec(HISTORY_TAB)
+                .setIndicator(resources.getString(R.string.tab_history),
+                resources.getDrawable(R.drawable.
+                browser_history_tab)).setContent(historyIntent));
+
+        String defaultTab = extras.getString(STARTING_TAB);
+        if (defaultTab != null) {
+            tabHost.setCurrentTab(2);
+        }
+    }
+
+    // Copied from DialTacts Activity
+    /** {@inheritDoc} */
+    public void onTabChanged(String tabId) {
+        Activity activity = getLocalActivityManager().getActivity(tabId);
+        if (activity != null) {
+            activity.onWindowFocusChanged(true);
+        }
+    }
+
+    
+}
diff --git a/src/com/android/browser/Dots.java b/src/com/android/browser/Dots.java
new file mode 100644
index 0000000..eb8d493
--- /dev/null
+++ b/src/com/android/browser/Dots.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright (C) 2008 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.Gravity;
+import android.widget.ImageView;
+import android.widget.LinearLayout;
+
+import java.util.Map;
+
+/**
+ * Displays a series of dots.  The selected one is highlighted.
+ * No animations yet.  Nothing fancy.
+ */
+class Dots extends LinearLayout {
+
+    private static final int MAX_DOTS = 8;
+    private int mSelected = -1;
+
+    public Dots(Context context) {
+        this(context, null);
+    }
+
+    public Dots(Context context, AttributeSet attrs) {
+        super(context, attrs);
+
+        setGravity(Gravity.CENTER);
+        setPadding(0, 4, 0, 4);
+
+        LayoutParams lp =
+                new LayoutParams(LayoutParams.WRAP_CONTENT,
+                                 LayoutParams.WRAP_CONTENT);
+
+        for (int i = 0; i < MAX_DOTS; i++) {
+            ImageView dotView = new ImageView(mContext);
+            dotView.setImageResource(R.drawable.page_indicator_unselected2);
+            addView(dotView, lp);
+        }
+    }
+
+    /**
+     * @param dotCount if less than 1 or greater than MAX_DOTS, Dots
+     * disappears
+     */
+    public void setDotCount(int dotCount) {
+        if (dotCount > 1 && dotCount <= MAX_DOTS) {
+            setVisibility(VISIBLE);
+            for (int i = 0; i < MAX_DOTS; i++) {
+                getChildAt(i).setVisibility(i < dotCount? VISIBLE : GONE);
+            }
+        } else {
+            setVisibility(GONE);
+        }
+    }
+
+    public void setSelected(int index) {
+        if (index < 0 || index >= MAX_DOTS) return;
+
+        if (mSelected >= 0) {
+            // Unselect old
+            ((ImageView)getChildAt(mSelected)).setImageResource(
+                    R.drawable.page_indicator_unselected2);
+        }
+        ((ImageView)getChildAt(index)).setImageResource(R.drawable.page_indicator);
+        mSelected = index;
+    }
+}
diff --git a/src/com/android/browser/FakeWebView.java b/src/com/android/browser/FakeWebView.java
new file mode 100644
index 0000000..633b799
--- /dev/null
+++ b/src/com/android/browser/FakeWebView.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright (C) 2008 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.Canvas;
+import android.graphics.Color;
+import android.graphics.Picture;
+import android.util.AttributeSet;
+import android.view.View;
+import android.webkit.WebView;
+import android.widget.ImageView;
+
+import android.util.Log;
+
+/**
+ *  This class is used by ImageAdapter to draw a representation of each tab. It 
+ *  overrides ImageView so it can be used for the new tab image as well.
+ */
+public class FakeWebView extends ImageView {
+    private TabControl.Tab mTab;
+    private Picture        mPicture;
+    private boolean        mUsesResource;
+
+    private class Listener implements WebView.PictureListener {
+        public void onNewPicture(WebView view, Picture p) {
+            FakeWebView.this.mPicture = p;
+            FakeWebView.this.invalidate();
+        }
+    };
+
+    public FakeWebView(Context context) {
+        this(context, null);
+    }
+    
+    public FakeWebView(Context context, AttributeSet attrs) {
+        this(context, attrs, 0);
+    }
+    
+    public FakeWebView(Context context, AttributeSet attrs, int defStyle) {
+        super(context, attrs, defStyle);
+    }
+
+    @Override
+    protected void onDraw(Canvas canvas) {
+        if (mUsesResource) {
+            super.onDraw(canvas);
+        } else {
+            // Always draw white behind the picture just in case the picture
+            // draws nothing.
+            // FIXME: We used to draw white only when the WebView was null but
+            // sometimes the picture was empty. So now we always draw white. It
+            // would be nice to know if the picture is empty so we can avoid
+            // drawing white.
+            canvas.drawColor(Color.WHITE);
+            if (mTab != null) {
+                final WebView w = mTab.getTopWindow();
+                if (w != null) {
+                    if (mPicture != null) {
+                        canvas.save();
+                        float scale = getWidth() * w.getScale() / w.getWidth();
+                        canvas.scale(scale, scale);
+                        canvas.translate(-w.getScrollX(), -w.getScrollY());
+                        canvas.drawPicture(mPicture);
+                        canvas.restore();
+                    }
+                }
+            }
+        }
+    }
+    
+    @Override
+    public void setImageResource(int resId) {
+        mUsesResource = true;
+        mTab = null;
+        super.setImageResource(resId);
+    }
+
+    /**
+     *  Set a WebView for this FakeWebView to represent.
+     *  @param  v WebView whose picture and other data will be used in onDraw.
+     */
+    public void setTab(TabControl.Tab t) {
+        mUsesResource = false;
+        mTab = t;
+        if (t != null && t.getWebView() != null) {
+            Listener l = new Listener();
+            if (t.getSubWebView() != null) {
+                t.getSubWebView().setPictureListener(l);
+            } else {
+                t.getWebView().setPictureListener(l);
+            }
+            mPicture = mTab.getTopWindow().capturePicture();
+        }
+    }
+}
diff --git a/src/com/android/browser/FetchUrlMimeType.java b/src/com/android/browser/FetchUrlMimeType.java
new file mode 100644
index 0000000..8578643
--- /dev/null
+++ b/src/com/android/browser/FetchUrlMimeType.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright (C) 2008 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.ContentValues;
+import android.net.Uri;
+import android.net.http.AndroidHttpClient;
+
+import org.apache.http.HttpResponse;
+import org.apache.http.Header;
+import org.apache.http.client.methods.HttpHead;
+
+import java.io.IOException;
+
+import android.os.AsyncTask;
+import android.provider.Downloads;
+import android.webkit.MimeTypeMap;
+import android.webkit.URLUtil;
+
+/**
+ * This class is used to pull down the http headers of a given URL so that
+ * we can analyse the mimetype and make any correction needed before we give
+ * the URL to the download manager. The ContentValues class holds the
+ * content that would be provided to the download manager, so that on
+ * completion of checking the mimetype, we can issue the download to
+ * the download manager.
+ * This operation is needed when the user long-clicks on a link or image and
+ * we don't know the mimetype. If the user just clicks on the link, we will
+ * do the same steps of correcting the mimetype down in
+ * android.os.webkit.LoadListener rather than handling it here.
+ *
+ */
+class FetchUrlMimeType extends AsyncTask<ContentValues, String, String> {
+
+    BrowserActivity mActivity;
+    ContentValues mValues;
+
+    public FetchUrlMimeType(BrowserActivity activity) {
+        mActivity = activity;
+    }
+
+    @Override
+    public String doInBackground(ContentValues... values) {
+        mValues = values[0];
+
+        // Check to make sure we have a URI to download
+        String uri = mValues.getAsString(Downloads.URI);
+        if (uri == null || uri.length() == 0) {
+            return null;
+        }
+
+        // User agent is likely to be null, though the AndroidHttpClient
+        // seems ok with that.
+        AndroidHttpClient client = AndroidHttpClient.newInstance(
+                mValues.getAsString(Downloads.USER_AGENT));
+        HttpHead request = new HttpHead(uri);
+
+        String cookie = mValues.getAsString(Downloads.COOKIE_DATA);
+        if (cookie != null && cookie.length() > 0) {
+            request.addHeader("Cookie", cookie);
+        }
+
+        String referer = mValues.getAsString(Downloads.REFERER);
+        if (referer != null && referer.length() > 0) {
+            request.addHeader("Referer", referer);
+        }
+
+        HttpResponse response;
+        Boolean succeeded = true;
+        String mimeType = null;
+        try {
+            response = client.execute(request);
+            // We could get a redirect here, but if we do lets let
+            // the download manager take care of it, and thus trust that
+            // the server sends the right mimetype
+            if (response.getStatusLine().getStatusCode() == 200) {
+                Header header = response.getFirstHeader("Content-Type");
+                if (header != null) {
+                    mimeType = header.getValue();
+                    final int semicolonIndex = mimeType.indexOf(';');
+                    if (semicolonIndex != -1) {
+                        mimeType = mimeType.substring(0, semicolonIndex);
+                    }
+                }
+            }
+        } catch (IllegalArgumentException ex) {
+            request.abort();
+        } catch (IOException ex) {
+            request.abort();
+        } finally {
+            client.close();
+        }
+
+        return mimeType;
+    }
+
+   @Override
+    public void onPostExecute(String mimeType) {
+       if (mimeType != null) {
+           String url = mValues.getAsString(Downloads.URI);
+           if (mimeType.equalsIgnoreCase("text/plain") ||
+                   mimeType.equalsIgnoreCase("application/octet-stream")) {
+               String newMimeType =
+                       MimeTypeMap.getSingleton().getMimeTypeFromExtension(
+                           MimeTypeMap.getFileExtensionFromUrl(url));
+               if (newMimeType != null) {
+                   mValues.put(Downloads.MIMETYPE, newMimeType);
+               }
+           }
+           String filename = URLUtil.guessFileName(url,
+                   null, mimeType);
+           mValues.put(Downloads.FILENAME_HINT, filename);
+       }
+
+       // Start the download
+       final Uri contentUri =
+           mActivity.getContentResolver().insert(Downloads.CONTENT_URI, mValues);
+       mActivity.viewDownloads(contentUri);
+    }
+
+}
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
new file mode 100644
index 0000000..43cd1c4
--- /dev/null
+++ b/src/com/android/browser/FindDialog.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2007 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.app.Dialog;
+import android.content.Context;
+import android.content.res.Configuration;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.TextWatcher;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
+import android.webkit.WebView;
+import android.widget.EditText;
+import android.widget.TextView;
+
+/* package */ class FindDialog extends Dialog implements TextWatcher {
+    private WebView         mWebView;
+    private TextView        mMatches;
+    private BrowserActivity mBrowserActivity;
+    
+    // Views with which the user can interact.
+    private View            mOk;
+    private EditText        mEditText;
+    private View            mNextButton;
+    private View            mPrevButton;
+    private View            mMatchesView;
+
+    private View.OnClickListener mFindListener = new View.OnClickListener() {
+        public void onClick(View v) {
+            findNext();
+        }
+    };
+
+    private View.OnClickListener mFindCancelListener  = 
+            new View.OnClickListener() {
+        public void onClick(View v) {
+            dismiss();
+        }
+    };
+    
+    private View.OnClickListener mFindPreviousListener  = 
+            new View.OnClickListener() {
+        public void onClick(View v) {
+            if (mWebView == null) {
+                throw new AssertionError("No WebView for FindDialog::onClick");
+            }
+            mWebView.findNext(false);
+            hideSoftInput();
+        }
+    };
+
+    /*
+     * Remove the soft keyboard from the screen.
+     */
+    private void hideSoftInput() {
+        InputMethodManager imm = (InputMethodManager)
+                mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
+        imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+    }
+
+    private void disableButtons() {
+        mPrevButton.setEnabled(false);
+        mNextButton.setEnabled(false);
+        mPrevButton.setFocusable(false);
+        mNextButton.setFocusable(false);
+    }
+
+    /* package */ void setWebView(WebView webview) {
+        mWebView = webview;
+    }
+
+    /* package */ FindDialog(BrowserActivity context) {
+        super(context, R.style.FindDialogTheme);
+        mBrowserActivity = context;
+        setCanceledOnTouchOutside(true);
+    }
+
+    /* package */ void onConfigurationChanged(Configuration newConfig) {
+        // FIXME: Would like to call mWebView.findAll again, so that the
+        // matches would refresh, but the new picture has not yet been
+        // created, so it is too soon.
+        mEditText.getText().clear();
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        Window theWindow = getWindow();
+        theWindow.setGravity(Gravity.BOTTOM|Gravity.FILL_HORIZONTAL);
+
+        setContentView(R.layout.browser_find);
+
+        theWindow.setLayout(ViewGroup.LayoutParams.FILL_PARENT,
+                ViewGroup.LayoutParams.WRAP_CONTENT);
+
+        mEditText = (EditText) findViewById(R.id.edit);
+        
+        View button = findViewById(R.id.next);
+        button.setOnClickListener(mFindListener);
+        mNextButton = button;
+        
+        button = findViewById(R.id.previous);
+        button.setOnClickListener(mFindPreviousListener);
+        mPrevButton = button;
+        
+        button = findViewById(R.id.done);
+        button.setOnClickListener(mFindCancelListener);
+        mOk = button;
+        
+        mMatches = (TextView) findViewById(R.id.matches);
+        mMatchesView = findViewById(R.id.matches_view);
+        disableButtons();
+        theWindow.setSoftInputMode(
+                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);
+    }
+    
+    public void dismiss() {
+        super.dismiss();
+        mBrowserActivity.closeFind();
+        mWebView.clearMatches();
+    }
+    
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        int code = event.getKeyCode();
+        boolean up = event.getAction() == KeyEvent.ACTION_UP;
+        switch (code) {
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                if (!mEditText.hasFocus()) {
+                    break;
+                }
+                if (up) {
+                    findNext();
+                }
+                return true;
+            default:
+                break;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+
+    private void findNext() {
+        if (mWebView == null) {
+            throw new AssertionError("No WebView for FindDialog::findNext");
+        }
+        mWebView.findNext(true);
+        hideSoftInput();
+    }
+
+    public void show() {
+        super.show();
+        mEditText.requestFocus();
+        mEditText.setText("");
+        Spannable span = (Spannable) mEditText.getText();
+        span.setSpan(this, 0, span.length(), 
+                     Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+        mMatches.setText(R.string.zero);
+        disableButtons();
+    }
+    
+    // TextWatcher methods
+    public void beforeTextChanged(CharSequence s, 
+                                  int start, 
+                                  int count, 
+                                  int after) {
+    }
+    
+    public void onTextChanged(CharSequence s,  
+                              int start, 
+                              int before, 
+                              int count) {
+        if (mWebView == null) {
+            throw new AssertionError(
+                    "No WebView for FindDialog::onTextChanged");
+        }
+        CharSequence find = mEditText.getText();
+        if (0 == find.length()) {
+            disableButtons();
+            mWebView.clearMatches();
+            mMatchesView.setVisibility(View.INVISIBLE);
+        } else {
+            mMatchesView.setVisibility(View.VISIBLE);
+            int found = mWebView.findAll(find.toString());
+            mMatches.setText(Integer.toString(found));
+            if (found < 2) {
+                disableButtons();
+                if (found == 0) {
+                    mMatches.setText(R.string.zero);
+                }
+            } else {
+                mPrevButton.setFocusable(true);
+                mNextButton.setFocusable(true);
+                mPrevButton.setEnabled(true);
+                mNextButton.setEnabled(true);
+            }
+        }
+    }
+
+    public void afterTextChanged(Editable s) {
+    }
+}
diff --git a/src/com/android/browser/GearsBaseDialog.java b/src/com/android/browser/GearsBaseDialog.java
new file mode 100644
index 0000000..638ba27
--- /dev/null
+++ b/src/com/android/browser/GearsBaseDialog.java
@@ -0,0 +1,474 @@
+/*
+ * Copyright (C) 2008 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.app.Activity;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+import android.os.Handler;
+import android.text.Spannable;
+import android.text.SpannableString;
+import android.text.style.UnderlineSpan;
+import android.util.Log;
+import android.view.InflateException;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.Button;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import java.io.InputStream;
+import java.io.IOException;
+import java.lang.ClassCastException;
+import java.net.HttpURLConnection;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Base dialog class for gears
+ */
+class GearsBaseDialog {
+
+  private static final String TAG = "GearsNativeDialog";
+  protected Handler mHandler;
+  protected Activity mActivity;
+  protected String mDialogArguments;
+
+  private Bitmap mIcon;
+  private final int MAX_ICON_SIZE = 64;
+  protected int mChoosenIconSize;
+
+  // Dialog closing types
+  public static final int CANCEL = 0;
+  public static final int ALWAYS_DENY = 1;
+  public static final int ALLOW = 2;
+  public static final int DENY = 3;
+  public static final int NEW_ICON = 4;
+  public static final int UPDATE_ICON = 5;
+  public static final int REQUEST_ICON = 6;
+  public static final int PAUSE_REQUEST_ICON = 7;
+  public static final int CLEAR_REQUEST_ICON = 8;
+
+  protected final String LOCAL_DATA_STRING = "localData";
+  protected final String LOCAL_STORAGE_STRING = "localStorage";
+  protected final String LOCATION_DATA_STRING = "locationData";
+
+  protected String mGearsVersion = "UNDEFINED";
+  protected boolean mDebug = false;
+
+  public GearsBaseDialog(Activity activity, Handler handler, String arguments) {
+    mActivity = activity;
+    mHandler = handler;
+    mDialogArguments = arguments;
+  }
+
+  Resources getResources() {
+    return mActivity.getResources();
+  }
+
+  Object getSystemService(String name) {
+    return mActivity.getSystemService(name);
+  }
+
+  View findViewById(int id) {
+    return mActivity.findViewById(id);
+  }
+
+  private String getString(int id) {
+    return mActivity.getString(id);
+  }
+
+  public void setDebug(boolean debug) {
+    mDebug = debug;
+  }
+
+  public void setGearsVersion(String version) {
+    mGearsVersion = version;
+  }
+
+  public String closeDialog(int closingType) {
+    return null;
+  }
+
+  /*
+   * Utility methods for setting up the dialogs elements
+   */
+
+  /**
+   * Inflate a given layout in a view (which has to be
+   * a ViewGroup, e.g. LinearLayout).
+   * This is used to share the basic dialog outline among
+   * the different dialog types.
+   */
+  void inflate(int layout, int viewID) {
+    LayoutInflater inflater = (LayoutInflater) getSystemService(
+        Context.LAYOUT_INFLATER_SERVICE);
+    View view = findViewById(viewID);
+    if (view != null) {
+      try {
+        ViewGroup viewGroup = (ViewGroup) view;
+        inflater.inflate(layout, viewGroup);
+      } catch (ClassCastException e) {
+        String msg = "exception, the view (" + view + ")";
+        msg += " is not a ViewGroup";
+        Log.e(TAG, msg, e);
+      } catch (InflateException e) {
+        Log.e(TAG, "exception while inflating the layout", e);
+      }
+    } else {
+      String msg = "problem, trying to inflate a non-existent view";
+      msg += " (" + viewID + ")";
+      Log.e(TAG, msg);
+    }
+  }
+
+  /**
+   * Button setup.
+   * Set the button's text and its listener. If the text resource's id
+   * is 0, makes the button invisible.
+   */
+  void setupButton(int buttonRscID,
+                   int rscString,
+                   View.OnClickListener listener,
+                   boolean isLink,
+                   boolean requestFocus) {
+    View view = findViewById(buttonRscID);
+    if (view == null) {
+      return;
+    }
+
+    Button button = (Button) view;
+
+    if (rscString == 0) {
+      button.setVisibility(View.GONE);
+    } else {
+      CharSequence text = getString(rscString);
+      button.setText(text);
+      button.setOnClickListener(listener);
+      if (isLink) {
+        displayAsLink(button);
+      }
+      if (requestFocus) {
+        button.requestFocus();
+      }
+    }
+  }
+
+  /**
+   * Button setup: as the above method, except that 'isLink' and
+   * 'requestFocus' default to false.
+   */
+  void setupButton(int buttonRsc, int rsc,
+                   View.OnClickListener listener) {
+    setupButton(buttonRsc, rsc, listener, false, false);
+  }
+
+  /**
+   * Utility method to setup the three dialog buttons.
+   */
+  void setupButtons(int alwaysDenyRsc, int allowRsc, int denyRsc) {
+    setupButton(R.id.button_alwaysdeny, alwaysDenyRsc,
+                new Button.OnClickListener() {
+                  public void onClick(View v) {
+                    mHandler.sendEmptyMessage(ALWAYS_DENY);
+                  }
+                });
+
+    setupButton(R.id.button_allow, allowRsc,
+                new Button.OnClickListener() {
+                  public void onClick(View v) {
+                    mHandler.sendEmptyMessage(ALLOW);
+                  }
+                });
+
+    setupButton(R.id.button_deny, denyRsc,
+                new Button.OnClickListener() {
+                  public void onClick(View v) {
+                    mHandler.sendEmptyMessage(DENY);
+                  }
+                });
+  }
+
+  /**
+   * Display a button as an HTML link. Remove the background, set the
+   * text color to R.color.dialog_link and draw an underline
+   */
+  void displayAsLink(Button button) {
+    if (button == null) {
+      return;
+    }
+
+    CharSequence text = button.getText();
+    button.setBackgroundDrawable(null);
+    int color = getResources().getColor(R.color.dialog_link);
+    button.setTextColor(color);
+    SpannableString str = new SpannableString(text);
+    str.setSpan(new UnderlineSpan(), 0, str.length(),
+                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
+    button.setText(str);
+    button.setFocusable(false);
+  }
+
+  /**
+   * Utility method to set elements' text indicated in
+   * the dialogs' arguments.
+   */
+  void setLabel(JSONObject json, String name, int rsc) {
+    try {
+      if (json.has(name)) {
+        String text = json.getString(name);
+        View view = findViewById(rsc);
+        if (view != null && text != null) {
+          TextView textView = (TextView) view;
+          textView.setText(text);
+          textView.setVisibility(View.VISIBLE);
+        }
+      }
+    } catch (JSONException e) {
+      Log.e(TAG, "json exception", e);
+    }
+  }
+
+  /**
+   * Utility method to hide a view.
+   */
+  void hideView(View v, int rsc) {
+    if (rsc == 0) {
+      return;
+    }
+    View view;
+    if (v == null) {
+      view = findViewById(rsc);
+    } else {
+      view = v.findViewById(rsc);
+    }
+    if (view != null) {
+      view.setVisibility(View.GONE);
+    }
+  }
+
+  /**
+   * Utility method to show a view.
+   */
+  void showView(View v, int rsc) {
+    if (rsc == 0) {
+      return;
+    }
+    View view;
+    if (v == null) {
+      view = findViewById(rsc);
+    } else {
+      view = v.findViewById(rsc);
+    }
+    if (view != null) {
+      view.setVisibility(View.VISIBLE);
+    }
+  }
+
+  /**
+   * Utility method to set a text.
+   */
+  void setText(View v, int rsc, CharSequence text) {
+    if (rsc == 0) {
+      return;
+    }
+    View view = v.findViewById(rsc);
+    if (view != null) {
+      TextView textView = (TextView) view;
+      textView.setText(text);
+      textView.setVisibility(View.VISIBLE);
+    }
+  }
+
+  /**
+   * Utility method to set a text.
+   */
+  void setText(View v, int rsc, int txtRsc) {
+    if (rsc == 0) {
+      return;
+    }
+    View view = v.findViewById(rsc);
+    if (view != null) {
+      TextView textView = (TextView) view;
+      if (txtRsc == 0) {
+        textView.setVisibility(View.GONE);
+      } else {
+        CharSequence text = getString(txtRsc);
+        textView.setText(text);
+        textView.setVisibility(View.VISIBLE);
+      }
+    }
+  }
+
+  /**
+   * Utility class to download an icon in the background.
+   * Once done ask the UI thread to update the icon.
+   */
+  class IconDownload implements Runnable {
+    private String mUrlString;
+
+    IconDownload(String url) {
+      mUrlString = url;
+    }
+
+    public void run() {
+      if (mUrlString == null) {
+        return;
+      }
+      try {
+        URL url = new URL(mUrlString);
+        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
+        connection.setDoInput(true);
+        connection.connect();
+        int length = connection.getContentLength();
+        InputStream is = connection.getInputStream();
+        Bitmap customIcon = BitmapFactory.decodeStream(is);
+        if (customIcon != null) {
+          mIcon = customIcon;
+          mHandler.sendEmptyMessage(UPDATE_ICON);
+        }
+      } catch (ClassCastException e) {
+        Log.e(TAG, "Class cast exception (" + mUrlString + ")", e);
+      } catch (MalformedURLException e) {
+        Log.e(TAG, "Malformed url (" + mUrlString + ") ", e);
+      } catch (IOException e) {
+        Log.e(TAG, "Exception downloading icon (" + mUrlString + ") ", e);
+      }
+    }
+  }
+
+  /**
+   * Utility method to update the icon.
+   * Called on the UI thread.
+   */
+  public void updateIcon() {
+    if (mIcon == null) {
+      return;
+    }
+    View view = findViewById(R.id.origin_icon);
+    if (view != null) {
+      ImageView imageView = (ImageView) view;
+      imageView.setMaxHeight(MAX_ICON_SIZE);
+      imageView.setMaxWidth(MAX_ICON_SIZE);
+      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
+      imageView.setImageBitmap(mIcon);
+      imageView.setVisibility(View.VISIBLE);
+    }
+  }
+
+  /**
+   * Utility method to download an icon from a url and set
+   * it to the GUI element R.id.origin_icon.
+   * It is used both in the shortcut dialog and the
+   * permission dialog.
+   * The actual download is done in the background via
+   * IconDownload; once the icon is downlowded the UI is updated
+   * via updateIcon().
+   * The icon size is included in the layout with the choosen
+   * size, although not displayed, to limit text reflow once
+   * the icon is received.
+   */
+  void downloadIcon(String url) {
+    if (url == null) {
+      return;
+    }
+    View view = findViewById(R.id.origin_icon);
+    if (view != null) {
+      view.setMinimumWidth(mChoosenIconSize);
+      view.setMinimumHeight(mChoosenIconSize);
+      view.setVisibility(View.INVISIBLE);
+    }
+    Thread thread = new Thread(new IconDownload(url));
+    thread.start();
+  }
+
+  /**
+   * Utility method that get the dialogMessage
+   * and icon and ask the setupDialog(message,icon)
+   * method to set the values.
+   */
+  public void setupDialog() {
+    TextView dialogMessage = null;
+    ImageView icon = null;
+
+    View view = findViewById(R.id.dialog_message);
+    if (view != null) {
+      dialogMessage = (TextView) view;
+    }
+
+    View iconView = findViewById(R.id.icon);
+    if (iconView != null) {
+      icon = (ImageView) iconView;
+    }
+
+    if ((dialogMessage != null) && (icon != null)) {
+      setupDialog(dialogMessage, icon);
+      dialogMessage.setVisibility(View.VISIBLE);
+    }
+  }
+
+  /*
+   * Set the message and icon of the dialog
+   */
+  public void setupDialog(TextView message, ImageView icon) {
+    message.setText(R.string.unrecognized_dialog_message);
+    icon.setImageResource(R.drawable.ic_dialog_menu_generic);
+    message.setVisibility(View.VISIBLE);
+  }
+
+  /**
+   * Setup the dialog
+   * By default, just display a simple message.
+   */
+  public void setup() {
+    setupButtons(0, 0, R.string.default_button);
+    setupDialog();
+  }
+
+  /**
+   * Method called when the back button is pressed,
+   * allowing the dialog to intercept the default behaviour.
+   */
+  public boolean handleBackButton() {
+    return false;
+  }
+
+  /**
+   * Returns the resource string of the notification displayed
+   * after the dialog. By default, does not return one.
+   */
+  public int notification() {
+    return 0;
+  }
+
+  /**
+   * If a secondary dialog (e.g. a confirmation dialog) is created,
+   * GearsNativeDialog will call this method.
+   */
+  public Dialog onCreateDialog(int id) {
+    // This should be redefined by subclasses as needed.
+    return null;
+  }
+
+}
diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java
new file mode 100644
index 0000000..ecf166d
--- /dev/null
+++ b/src/com/android/browser/GearsNativeDialog.java
@@ -0,0 +1,280 @@
+/*
+ * Copyright (C) 2008 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.app.Activity;
+import android.app.Dialog;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
+import android.util.Config;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.KeyEvent;
+import android.view.Window;
+import android.widget.BaseAdapter;
+import android.widget.Toast;
+
+import android.webkit.gears.NativeDialog;
+
+import com.android.browser.GearsBaseDialog;
+import com.android.browser.GearsPermissionsDialog;
+import com.android.browser.GearsSettingsDialog;
+
+/**
+ * Native dialog Activity used by gears
+ * TODO: rename in GearsNativeDialogActivity
+ * @hide
+ */
+public class GearsNativeDialog extends Activity {
+
+  private static final String TAG = "GearsNativeDialog";
+
+  private String mDialogArguments;
+
+  private String mGearsVersion = null;
+
+  private boolean mDebug = false;
+
+  private int mDialogType;
+  private final int SETTINGS_DIALOG = 1;
+  private final int PERMISSION_DIALOG = 2;
+  private final int LOCATION_DIALOG = 3;
+
+  private final String VERSION_STRING = "version";
+  private final String SETTINGS_DIALOG_STRING = "settings_dialog";
+  private final String PERMISSION_DIALOG_STRING = "permissions_dialog";
+  private final String LOCATION_DIALOG_STRING = "locations_dialog";
+
+  private boolean mDialogDismissed = false;
+
+  GearsBaseDialog dialog;
+
+  // Handler for callbacks to the UI thread
+  final Handler mHandler = new Handler() {
+    public void handleMessage(Message msg) {
+      if (msg.what == GearsBaseDialog.NEW_ICON) {
+        BaseAdapter adapter = (BaseAdapter) msg.obj;
+        adapter.notifyDataSetChanged();
+      } else if (msg.what == GearsBaseDialog.UPDATE_ICON) {
+        dialog.updateIcon();
+      } else if (msg.what == GearsBaseDialog.ALWAYS_DENY) {
+        closeDialog(GearsBaseDialog.ALWAYS_DENY);
+      } else if (msg.what == GearsBaseDialog.ALLOW) {
+        closeDialog(GearsBaseDialog.ALLOW);
+      } else if (msg.what == GearsBaseDialog.DENY) {
+        closeDialog(GearsBaseDialog.DENY);
+      }
+      super.handleMessage(msg);
+    }
+  };
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    getArguments();
+    if (mDialogType == SETTINGS_DIALOG) {
+      setTheme(android.R.style.Theme);
+    }
+    super.onCreate(icicle);
+    if (mDialogType != SETTINGS_DIALOG) {
+      requestWindowFeature(Window.FEATURE_NO_TITLE);
+      setContentView(R.layout.gears_dialog);
+    }
+
+    switch (mDialogType) {
+      case SETTINGS_DIALOG:
+        dialog = new GearsSettingsDialog(this, mHandler, mDialogArguments);
+        dialog.setGearsVersion(mGearsVersion);
+        break;
+      case PERMISSION_DIALOG:
+        dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
+        break;
+      case LOCATION_DIALOG:
+        dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
+        break;
+      default:
+        dialog = new GearsBaseDialog(this, mHandler, mDialogArguments);
+    }
+    dialog.setDebug(mDebug);
+    dialog.setup();
+  }
+
+  /**
+   * Get the arguments for the dialog
+   *
+   * The dialog needs a json string as an argument, as
+   * well as a dialogType. In debug mode the arguments
+   * are mocked.
+   */
+  private void getArguments() {
+    if (mDebug) {
+      mDialogType = LOCATION_DIALOG +1;
+      mockArguments();
+
+      return;
+    }
+
+    Intent intent = getIntent();
+    mDialogArguments = intent.getStringExtra("dialogArguments");
+    String dialogTypeString = intent.getStringExtra("dialogType");
+    if (dialogTypeString == null) {
+      return;
+    }
+
+    if (Config.LOGV) {
+      Log.v(TAG, "dialogtype: " + dialogTypeString);
+    }
+
+    if (dialogTypeString.equalsIgnoreCase(SETTINGS_DIALOG_STRING)) {
+      mDialogType = SETTINGS_DIALOG;
+      mGearsVersion = intent.getStringExtra(VERSION_STRING);
+    } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) {
+      mDialogType = PERMISSION_DIALOG;
+    } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) {
+      mDialogType = LOCATION_DIALOG;
+    }
+  }
+
+  /**
+   * Utility method for debugging the dialog.
+   *
+   * Set mock arguments.
+   */
+  private void mockArguments() {
+
+    String argumentsPermissions = "{ locale: \"en-US\", "
+        + "origin: \"http://www.google.com\", dialogType: \"localData\","
+        + "customIcon: \"http://google-gears.googlecode.com/"
+        + "svn/trunk/gears/test/manual/shortcuts/32.png\","
+        + "customName: \"My Application\","
+        + "customMessage: \"Press the button to enable my "
+        + "application to run offline!\" };";
+
+    String argumentsPermissions2 = "{ locale: \"en-US\", "
+        + "origin: \"http://www.google.com\", dialogType: \"localData\" };";
+
+    String argumentsLocation = "{ locale: \"en-US\", "
+        + "origin: \"http://www.google.com\", dialogType: \"locationData\","
+        + "customIcon: \"http://google-gears.googlecode.com/"
+        + "svn/trunk/gears/test/manual/shortcuts/32.png\","
+        + "customName: \"My Application\","
+        + "customMessage: \"Press the button to enable my "
+        + "application to run offline!\" };";
+
+    String argumentsSettings = "{ locale: \"en-US\", permissions: [ { "
+        + "name: \"http://www.google.com\", "
+        + "localStorage: { permissionState: 0 }, "
+        + "locationData: { permissionState: 1 } }, "
+        + "{ name: \"http://www.aaronboodman.com\", "
+        + "localStorage: { permissionState: 1 }, "
+        + "locationData: { permissionState: 2 } }, "
+        + "{ name: \"http://www.evil.org\", "
+        + "localStorage: { permissionState: 2 }, "
+        + "locationData: { permissionState: 2 } } ] }";
+
+    switch (mDialogType) {
+      case PERMISSION_DIALOG:
+        mDialogArguments = argumentsPermissions;
+        break;
+      case LOCATION_DIALOG:
+        mDialogArguments = argumentsLocation;
+        break;
+      case SETTINGS_DIALOG:
+        mDialogArguments = argumentsSettings;
+        break;
+    }
+  }
+
+  /**
+   * Close the dialog and set the return string value.
+   */
+  private void closeDialog(int closingType) {
+    String ret = dialog.closeDialog(closingType);
+
+    if (mDebug) {
+      Log.v(TAG, "closeDialog ret value: " + ret);
+    }
+
+    NativeDialog.closeDialog(ret);
+    notifyEndOfDialog();
+    finish();
+
+    // If the dialog sets a notification, we display it.
+    int notification = dialog.notification();
+    if (notification != 0) {
+      Toast toast = Toast.makeText(this, notification, Toast.LENGTH_LONG);
+      toast.setGravity(Gravity.BOTTOM, 0, 0);
+      toast.show();
+    }
+  }
+
+  @Override
+  public void onDestroy() {
+    super.onDestroy();
+    // In case we reach this point without
+    // notifying NativeDialog, we do it now.
+    if (!mDialogDismissed) {
+      notifyEndOfDialog();
+    }
+  }
+
+  @Override
+  public void onPause(){
+    super.onPause();
+    if (!mDialogDismissed) {
+      closeDialog(GearsBaseDialog.CANCEL);
+    }
+  }
+
+  /**
+   * Signal to NativeDialog that we are done.
+   */
+  private void notifyEndOfDialog() {
+    NativeDialog.signalFinishedDialog();
+    mDialogDismissed = true;
+  }
+
+  /**
+   * Intercepts the back key to immediately notify
+   * NativeDialog that we are done.
+   */
+  public boolean dispatchKeyEvent(KeyEvent event) {
+    if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
+      && (event.getAction() == KeyEvent.ACTION_DOWN)) {
+      if (!dialog.handleBackButton()) {
+        // if the dialog doesn't do anything with the back button
+        closeDialog(GearsBaseDialog.CANCEL);
+      }
+      return true; // event consumed
+    }
+    return super.dispatchKeyEvent(event);
+  }
+
+  /**
+   * If the dialog call showDialog() on ourself, we let
+   * it handle the creation of this secondary dialog.
+   * It is used in GearsSettingsDialog, to create the confirmation
+   * dialog when the user click on "Remove this site from Gears"
+   */
+  @Override
+  protected Dialog onCreateDialog(int id) {
+    return dialog.onCreateDialog(id);
+  }
+
+}
diff --git a/src/com/android/browser/GearsPermissions.java b/src/com/android/browser/GearsPermissions.java
new file mode 100644
index 0000000..e48e045
--- /dev/null
+++ b/src/com/android/browser/GearsPermissions.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright (C) 2008 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.util.Log;
+
+import java.util.HashMap;
+import java.util.Iterator;
+
+/**
+ * The permission mechanism works the following way:
+ *
+ * PermissionType allows to define a type of permission
+ *   (e.g. localStorage/locationData), storing a name and a set of
+ *   resource ids corresponding to the GUI resources.
+ *
+ * Permission defines an actual permission instance, with a type and a value.
+ *
+ * OriginPermissions holds an origin with a set of Permission objects
+ */
+class GearsPermissions {
+
+  private static final String TAG = "GearsPermissions";
+
+  /**
+   * Defines a type of permission
+   *
+   * Store the permission's name (used in the json result)
+   * Graphically, each permission is a label followed by two radio buttons.
+   * We store the resources ids here.
+   */
+  public static class PermissionType {
+    public static final int PERMISSION_NOT_SET = 0;
+    public static final int PERMISSION_ALLOWED = 1;
+    public static final int PERMISSION_DENIED = 2;
+
+    String mName;
+    int mTitleRsc;
+    int mSubtitleOnRsc;
+    int mSubtitleOffRsc;
+
+    PermissionType(String name) {
+      mName = name;
+    }
+
+    public void setResources(int titleRsc,
+        int subtitleOnRsc, int subtitleOffRsc) {
+      mTitleRsc = titleRsc;
+      mSubtitleOnRsc = subtitleOnRsc;
+      mSubtitleOffRsc = subtitleOffRsc;
+    }
+
+    public String getName() {
+      return mName;
+    }
+
+    public int getTitleRsc() {
+      return mTitleRsc;
+    }
+
+    public int getSubtitleOnRsc() {
+      return mSubtitleOnRsc;
+    }
+
+    public int getSubtitleOffRsc() {
+      return mSubtitleOffRsc;
+    }
+
+  }
+
+  /**
+   * Simple class to store an instance of a permission
+   *
+   * i.e. a permission type and a value
+   * Value can be either PERMISSION_NOT_SET,
+   * PERMISSION_ALLOWED or PERMISSION_DENIED
+   * (defined in PermissionType).
+   */
+  public static class Permission {
+    PermissionType mType;
+    int mValue;
+
+    Permission(PermissionType type, int value) {
+      mType = type;
+      mValue = value;
+    }
+
+    Permission(PermissionType type) {
+      mType = type;
+      mValue = 0;
+    }
+
+    public PermissionType getType() {
+      return mType;
+    }
+
+    public void setValue(int value) {
+      mValue = value;
+    }
+
+    public int getValue() {
+      return mValue;
+    }
+  }
+
+  /**
+   * Interface used by the GearsNativeDialog implementation
+   * to listen to changes in the permissions.
+   */
+  public interface PermissionsChangesListener {
+    public boolean setPermission(PermissionType type, int perm);
+  }
+
+  /**
+   * Holds the model for an origin -- each origin has a set of
+   * permissions.
+   */
+  public static class OriginPermissions {
+    HashMap<PermissionType, Permission> mPermissions;
+    String mOrigin;
+    public static PermissionsChangesListener mListener;
+
+    public static void setListener(PermissionsChangesListener listener) {
+      mListener = listener;
+    }
+
+    OriginPermissions(String anOrigin) {
+      mOrigin = anOrigin;
+      mPermissions = new HashMap<PermissionType, Permission>();
+    }
+
+    OriginPermissions(OriginPermissions perms) {
+      mOrigin = perms.getOrigin();
+      mPermissions = new HashMap<PermissionType, Permission>();
+      HashMap<PermissionType, Permission> permissions = perms.getPermissions();
+      Iterator<PermissionType> iterator = permissions.keySet().iterator();
+      while (iterator.hasNext()) {
+        Permission permission = permissions.get(iterator.next());
+        int value = permission.getValue();
+        setPermission(permission.getType(), value);
+      }
+    }
+
+    public String getOrigin() {
+      return mOrigin;
+    }
+
+    public HashMap<PermissionType, Permission> getPermissions() {
+      return mPermissions;
+    }
+
+    public int getPermission(PermissionType type) {
+      return mPermissions.get(type).getValue();
+    }
+
+    public void setPermission(PermissionType type, int perm) {
+      if (mPermissions.get(type) == null) {
+        Permission permission = new Permission(type, perm);
+        mPermissions.put(type, permission);
+        return;
+      }
+
+      if (mListener != null) {
+        mListener.setPermission(type, perm);
+      }
+
+      mPermissions.get(type).setValue(perm);
+    }
+
+    public void print() {
+      Log.v(TAG, "Permissions for " + mOrigin);
+      Iterator<PermissionType> iterator = mPermissions.keySet().iterator();
+      while (iterator.hasNext()) {
+        Permission permission = mPermissions.get(iterator.next());
+        String name = permission.getType().getName();
+        int value = permission.getValue();
+        Log.v(TAG, "  " + name + ": " + value);
+      }
+    }
+  }
+
+}
diff --git a/src/com/android/browser/GearsPermissionsDialog.java b/src/com/android/browser/GearsPermissionsDialog.java
new file mode 100644
index 0000000..dbec363
--- /dev/null
+++ b/src/com/android/browser/GearsPermissionsDialog.java
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2008 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.app.Activity;
+import android.os.Handler;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.View;
+import android.widget.ImageView;
+import android.widget.TextView;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Gears permission dialog
+ */
+class GearsPermissionsDialog extends GearsBaseDialog {
+
+  private static final String TAG = "GearsPermissionsDialog";
+
+  private String mDialogType;
+  private int mNotification = 0;
+
+  public GearsPermissionsDialog(Activity activity,
+                                Handler handler,
+                                String arguments) {
+    super (activity, handler, arguments);
+  }
+
+  public void setup() {
+    inflate(R.layout.gears_dialog_permission, R.id.panel_content);
+    setupButtons(R.string.permission_button_alwaysdeny,
+                 R.string.permission_button_allow,
+                 R.string.permission_button_deny);
+
+    try {
+      JSONObject json = new JSONObject(mDialogArguments);
+
+      if (json.has("dialogType")) {
+        mDialogType = json.getString("dialogType");
+        setupDialog();
+      }
+
+      if (!json.has("customName")) {
+        setLabel(json, "origin", R.id.origin_title);
+        View titleView = findViewById(R.id.origin_title);
+        if (titleView != null) {
+          TextView title = (TextView) titleView;
+          title.setGravity(Gravity.CENTER);
+        }
+      } else {
+        setLabel(json, "customName", R.id.origin_title);
+        setLabel(json, "origin", R.id.origin_subtitle);
+        setLabel(json, "customMessage", R.id.origin_message);
+      }
+
+      if (json.has("customIcon")) {
+        String iconUrl = json.getString("customIcon");
+        mChoosenIconSize = 32;
+        downloadIcon(iconUrl);
+      }
+
+      View msg = findViewById(R.id.permission_dialog_message);
+      if (msg != null) {
+        TextView dialogMessage = (TextView) msg;
+        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
+          dialogMessage.setText(R.string.query_data_message);
+        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
+          dialogMessage.setText(R.string.location_message);
+        }
+      }
+
+    } catch (JSONException e) {
+      Log.e(TAG, "JSON exception ", e);
+    }
+  }
+
+  public void setupDialog(TextView message, ImageView icon) {
+    if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
+      message.setText(R.string.query_data_prompt);
+      icon.setImageResource(android.R.drawable.ic_popup_disk_full);
+    } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
+      message.setText(R.string.location_prompt);
+      icon.setImageResource(R.drawable.ic_dialog_menu_generic);
+    }
+  }
+
+  public String closeDialog(int closingType) {
+    String ret = null;
+    switch (closingType) {
+      case ALWAYS_DENY:
+        ret = "{\"allow\": false, \"permanently\": true }";
+        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
+          mNotification = R.string.storage_notification_alwaysdeny;
+        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
+          mNotification = R.string.location_notification_alwaysdeny;
+        }
+        break;
+      case ALLOW:
+        ret = "{\"allow\": true, \"permanently\": true }";
+        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
+          mNotification = R.string.storage_notification;
+        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
+          mNotification = R.string.location_notification;
+        }
+        break;
+      case DENY:
+        ret = "{\"allow\": false, \"permanently\": false }";
+        break;
+    }
+    return ret;
+  }
+
+  public int notification() {
+    return mNotification;
+  }
+}
diff --git a/src/com/android/browser/GearsSettingsDialog.java b/src/com/android/browser/GearsSettingsDialog.java
new file mode 100644
index 0000000..5ea2342
--- /dev/null
+++ b/src/com/android/browser/GearsSettingsDialog.java
@@ -0,0 +1,460 @@
+/*
+ * Copyright (C) 2008 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.app.Activity;
+import android.app.AlertDialog;
+import android.app.Dialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.os.Handler;
+import android.util.Log;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ArrayAdapter;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.BaseAdapter;
+import android.widget.Button;
+import android.widget.CheckBox;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.RadioButton;
+import android.widget.TextView;
+
+import com.android.browser.GearsPermissions.OriginPermissions;
+import com.android.browser.GearsPermissions.Permission;
+import com.android.browser.GearsPermissions.PermissionsChangesListener;
+import com.android.browser.GearsPermissions.PermissionType;
+
+import java.util.Vector;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * Gears Settings dialog
+ */
+class GearsSettingsDialog extends GearsBaseDialog
+    implements PermissionsChangesListener {
+
+  private static final String TAG = "GearsPermissionsDialog";
+  private Vector<OriginPermissions> mSitesPermissions = null;
+  private Vector<OriginPermissions> mOriginalPermissions = null;
+  private Vector<OriginPermissions> mCurrentPermissions = null;
+
+  private Vector<PermissionType> mPermissions;
+  private static final int CONFIRMATION_REMOVE_DIALOG = 1;
+
+  // We declare the permissions globally to simplify the code
+  private final PermissionType LOCAL_STORAGE =
+      new PermissionType(LOCAL_STORAGE_STRING);
+  private final PermissionType LOCATION_DATA =
+      new PermissionType(LOCATION_DATA_STRING);
+
+  private boolean mChanges = false;
+
+  SettingsAdapter mListAdapter;
+
+  public GearsSettingsDialog(Activity activity,
+                             Handler handler,
+                             String arguments) {
+    super (activity, handler, arguments);
+    activity.setContentView(R.layout.gears_settings);
+  }
+
+  public void setup() {
+    // First let's add the permissions' resources
+    LOCAL_STORAGE.setResources(R.string.settings_storage_title,
+                               R.string.settings_storage_subtitle_on,
+                               R.string.settings_storage_subtitle_off);
+    LOCATION_DATA.setResources(R.string.settings_location_title,
+                               R.string.settings_location_subtitle_on,
+                               R.string.settings_location_subtitle_off);
+    // add the permissions to the list of permissions.
+    mPermissions = new Vector<PermissionType>();
+    mPermissions.add(LOCAL_STORAGE);
+    mPermissions.add(LOCATION_DATA);
+    OriginPermissions.setListener(this);
+
+
+    setupDialog();
+
+    // We manage the permissions using three vectors, mSitesPermissions,
+    // mOriginalPermissions and mCurrentPermissions.
+    // The dialog's arguments are parsed and a list of permissions is
+    // generated and stored in those three vectors.
+    // mOriginalPermissions is a separate copy and will not be modified;
+    // mSitesPermissions contains the current permissions _only_ --
+    // if an origin is removed, it is also removed from mSitesPermissions.
+    // Finally, mCurrentPermissions contains the current permissions and
+    // is a clone of mSitesPermissions, but removed sites aren't removed,
+    // their permissions are simply set to PERMISSION_NOT_SET. This
+    // allows us to easily generate the final difference between the
+    // original permissions and the final permissions, while directly
+    // using mSitesPermissions for the listView adapter (SettingsAdapter).
+
+    mSitesPermissions = new Vector<OriginPermissions>();
+    mOriginalPermissions = new Vector<OriginPermissions>();
+
+    try {
+      JSONObject json = new JSONObject(mDialogArguments);
+      if (json.has("permissions")) {
+        JSONArray jsonArray = json.getJSONArray("permissions");
+        for (int i = 0; i < jsonArray.length(); i++) {
+          JSONObject infos = jsonArray.getJSONObject(i);
+          String name = null;
+          int localStorage = PermissionType.PERMISSION_NOT_SET;
+          int locationData = PermissionType.PERMISSION_NOT_SET;
+          if (infos.has("name")) {
+            name = infos.getString("name");
+          }
+          if (infos.has(LOCAL_STORAGE_STRING)) {
+            JSONObject perm = infos.getJSONObject(LOCAL_STORAGE_STRING);
+            if (perm.has("permissionState")) {
+              localStorage = perm.getInt("permissionState");
+            }
+          }
+          if (infos.has(LOCATION_DATA_STRING)) {
+            JSONObject perm = infos.getJSONObject(LOCATION_DATA_STRING);
+            if (perm.has("permissionState")) {
+              locationData = perm.getInt("permissionState");
+            }
+          }
+          OriginPermissions perms = new OriginPermissions(name);
+          perms.setPermission(LOCAL_STORAGE, localStorage);
+          perms.setPermission(LOCATION_DATA, locationData);
+
+          mSitesPermissions.add(perms);
+          mOriginalPermissions.add(new OriginPermissions(perms));
+        }
+      }
+    } catch (JSONException e) {
+      Log.e(TAG, "JSON exception ", e);
+    }
+    mCurrentPermissions = (Vector<OriginPermissions>)mSitesPermissions.clone();
+
+    View listView = findViewById(R.id.sites_list);
+    if (listView != null) {
+      ListView list = (ListView) listView;
+      mListAdapter = new SettingsAdapter(mActivity, mSitesPermissions);
+      list.setAdapter(mListAdapter);
+      list.setScrollBarStyle(android.view.View.SCROLLBARS_OUTSIDE_INSET);
+      list.setOnItemClickListener(mListAdapter);
+    }
+    if (mDebug) {
+      printPermissions();
+    }
+  }
+
+  private void setMainTitle() {
+    String windowTitle = mActivity.getString(R.string.pref_extras_gears_settings);
+    mActivity.setTitle(windowTitle);
+  }
+
+  public void setupDialog() {
+    setMainTitle();
+  }
+
+  /**
+   * GearsPermissions.PermissionsChangesListener delegate
+   */
+  public boolean setPermission(PermissionType type, int perm) {
+    if (mChanges == false) {
+      mChanges = true;
+    }
+    return mChanges;
+  }
+
+  public boolean handleBackButton() {
+    return mListAdapter.backButtonPressed();
+  }
+
+  /**
+   * We use this to create a confirmation dialog when the user
+   * clicks on "remove this site from gears"
+   */
+  public Dialog onCreateDialog(int id) {
+    return new AlertDialog.Builder(mActivity)
+        .setTitle(R.string.settings_confirmation_remove_title)
+        .setMessage(R.string.settings_confirmation_remove)
+        .setPositiveButton(android.R.string.ok,
+                           new AlertDialog.OnClickListener() {
+          public void onClick(DialogInterface dlg, int which) {
+            mListAdapter.removeCurrentSite();
+          }
+        })
+        .setNegativeButton(android.R.string.cancel, null)
+        .setIcon(android.R.drawable.ic_dialog_alert)
+        .create();
+  }
+
+  /**
+   * Adapter class for the list view in the settings dialog
+   *
+   * We first display a list of all the origins (sites), or
+   * a message saying that no permission is set if the list is empty.
+   * When the user click on one of the origin, we then display
+   * the list of the permissions existing for that origin.
+   * Each permission can be either allowed or denied by clicking
+   * on the checkbox.
+   * The last row is a special case, allowing to remove the entire origin.
+   */
+  class SettingsAdapter extends BaseAdapter
+      implements AdapterView.OnItemClickListener {
+    private Activity mContext;
+    private List mItems;
+    private OriginPermissions mCurrentSite;
+    private Vector mCurrentPermissions;
+    private int MAX_ROW_HEIGHT = 64;
+
+    SettingsAdapter(Activity context, List items) {
+      mContext = context;
+      mItems = items;
+      mCurrentSite = null;
+    }
+
+    public int getCount() {
+      if (mCurrentSite == null) {
+        int size = mItems.size();
+        if (size == 0) {
+          return 1;
+        } else {
+          return size;
+        }
+      }
+      return mCurrentPermissions.size() + 1;
+    }
+
+    public long getItemId(int position) {
+      return position;
+    }
+
+    private String shortName(String url) {
+        // We remove the http and https prefix
+        if (url.startsWith("http://")) {
+          return url.substring(7);
+        }
+        if (url.startsWith("https://")) {
+          return url.substring(8);
+        }
+        return url;
+    }
+
+    public Object getItem(int position) {
+      if (mCurrentSite == null) {
+        if (mItems.size() == 0) {
+          return null;
+        } else {
+          return mItems.get(position);
+        }
+      }
+      return mCurrentPermissions.get(position);
+    }
+
+    public View getView(int position, View convertView, ViewGroup parent) {
+      View row = convertView;
+      if (row == null) { // no cached view, we create one
+        LayoutInflater inflater = (LayoutInflater) getSystemService(
+            Context.LAYOUT_INFLATER_SERVICE);
+        row = inflater.inflate(R.layout.gears_settings_row, null);
+      }
+      row.setMinimumHeight(MAX_ROW_HEIGHT);
+
+      if (mCurrentSite == null) {
+        if (mItems.size() == 0) {
+          hideView(row, R.id.title);
+          hideView(row, R.id.subtitle);
+          hideView(row, R.id.checkbox);
+          hideView(row, R.id.icon);
+          setText(row, R.id.info, R.string.settings_empty);
+        } else {
+          hideView(row, R.id.subtitle);
+          hideView(row, R.id.info);
+          hideView(row, R.id.checkbox);
+          OriginPermissions perms = (OriginPermissions) mItems.get(position);
+          setText(row, R.id.title, shortName(perms.getOrigin()));
+          showView(row, R.id.icon);
+        }
+      } else {
+        if (position == getCount() - 1) {
+          // last position: "remove this site from gears"
+          hideView(row, R.id.subtitle);
+          hideView(row, R.id.info);
+          hideView(row, R.id.checkbox);
+          hideView(row, R.id.icon);
+          setText(row, R.id.title, R.string.settings_remove_site);
+        } else {
+          hideView(row, R.id.info);
+          hideView(row, R.id.icon);
+          showView(row, R.id.checkbox);
+
+          PermissionType type =
+              (PermissionType) mCurrentPermissions.get(position);
+          setText(row, R.id.title, type.getTitleRsc());
+
+          View checkboxView = row.findViewById(R.id.checkbox);
+          if (checkboxView != null) {
+            CheckBox checkbox = (CheckBox) checkboxView;
+            int perm = mCurrentSite.getPermission(type);
+            if (perm == PermissionType.PERMISSION_DENIED) {
+              setText(row, R.id.subtitle, type.getSubtitleOffRsc());
+              checkbox.setChecked(false);
+            } else {
+              setText(row, R.id.subtitle, type.getSubtitleOnRsc());
+              checkbox.setChecked(true);
+            }
+          }
+        }
+      }
+      return row;
+    }
+
+    public void removeCurrentSite() {
+      mCurrentSite.setPermission(LOCAL_STORAGE,
+                                 PermissionType.PERMISSION_NOT_SET);
+      mCurrentSite.setPermission(LOCATION_DATA,
+                                 PermissionType.PERMISSION_NOT_SET);
+      mSitesPermissions.remove(mCurrentSite);
+      mCurrentSite = null;
+      setMainTitle();
+      notifyDataSetChanged();
+    }
+
+    public void onItemClick(AdapterView<?> parent,
+                            View view,
+                            int position,
+                            long id) {
+      if (mItems.size() == 0) {
+        return;
+      }
+      if (mCurrentSite == null) {
+         mCurrentSite = (OriginPermissions) mItems.get(position);
+         mCurrentPermissions = new Vector();
+         for (int i = 0; i < mPermissions.size(); i++) {
+           PermissionType type = mPermissions.get(i);
+           int perm = mCurrentSite.getPermission(type);
+           if (perm != PermissionType.PERMISSION_NOT_SET) {
+             mCurrentPermissions.add(type);
+           }
+         }
+         mContext.setTitle(shortName(mCurrentSite.getOrigin()));
+      } else {
+        if (position == getCount() - 1) { // last item (remove site)
+          // Ask the user to confirm
+          // If yes, removeCurrentSite() will be called via the dialog callback.
+          mActivity.showDialog(CONFIRMATION_REMOVE_DIALOG);
+        } else {
+          PermissionType type =
+              (PermissionType) mCurrentPermissions.get(position);
+          if (mCurrentSite.getPermission(type) ==
+              PermissionType.PERMISSION_ALLOWED) {
+            mCurrentSite.setPermission(type, PermissionType.PERMISSION_DENIED);
+          } else {
+            mCurrentSite.setPermission(type, PermissionType.PERMISSION_ALLOWED);
+          }
+        }
+      }
+      notifyDataSetChanged();
+    }
+
+    public boolean backButtonPressed() {
+      if (mCurrentSite != null) { // we intercept the back button
+        mCurrentSite = null;
+        setMainTitle();
+        notifyDataSetChanged();
+        return true;
+      }
+      return false;
+    }
+
+  }
+
+  /**
+   * Utility method used in debug mode to print the list of
+   * permissions (original values and current values).
+   */
+  public void printPermissions() {
+    Log.v(TAG, "Original Permissions: ");
+    for (int i = 0; i < mOriginalPermissions.size(); i++) {
+      OriginPermissions p = mOriginalPermissions.get(i);
+      p.print();
+    }
+    Log.v(TAG, "Current Permissions: ");
+    for (int i = 0; i < mSitesPermissions.size(); i++) {
+      OriginPermissions p = mSitesPermissions.get(i);
+      p.print();
+    }
+  }
+
+  /**
+   * Computes the difference between the original permissions and the
+   * current ones. Returns a json-formatted string.
+   * It is used by the Settings dialog.
+   */
+  public String computeDiff(boolean modif) {
+    String ret = null;
+    try {
+      JSONObject results = new JSONObject();
+      JSONArray permissions = new JSONArray();
+
+      for (int i = 0; modif && i < mOriginalPermissions.size(); i++) {
+        OriginPermissions original = mOriginalPermissions.get(i);
+        OriginPermissions current = mCurrentPermissions.get(i);
+        JSONObject permission = new JSONObject();
+        boolean modifications = false;
+
+        for (int j = 0; j < mPermissions.size(); j++) {
+          PermissionType type = mPermissions.get(j);
+
+          if (current.getPermission(type) != original.getPermission(type)) {
+            JSONObject state = new JSONObject();
+            state.put("permissionState", current.getPermission(type));
+            permission.put(type.getName(), state);
+            modifications = true;
+          }
+        }
+
+        if (modifications) {
+          permission.put("name", current.getOrigin());
+          permissions.put(permission);
+        }
+      }
+      results.put("modifiedOrigins", permissions);
+      ret = results.toString();
+    } catch (JSONException e) {
+      Log.e(TAG, "JSON exception ", e);
+    }
+    return ret;
+  }
+
+  public String closeDialog(int closingType) {
+    String ret = computeDiff(mChanges);
+
+    if (mDebug) {
+      printPermissions();
+    }
+
+    return ret;
+  }
+
+}
diff --git a/src/com/android/browser/HistoryItem.java b/src/com/android/browser/HistoryItem.java
new file mode 100644
index 0000000..55e43f0
--- /dev/null
+++ b/src/com/android/browser/HistoryItem.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2008 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.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.database.Cursor;
+import android.graphics.Bitmap;
+import android.net.Uri;
+import android.provider.Browser;
+import android.util.Log;
+import android.view.View;
+import android.webkit.WebIconDatabase;
+import android.widget.CompoundButton;
+import android.widget.ImageView;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import java.util.Date;
+
+/**
+ *  Layout representing a history item in the classic history viewer.
+ */
+/* package */ class HistoryItem extends BookmarkItem {
+
+    private CompoundButton  mStar;      // Star for bookmarking
+    private CompoundButton.OnCheckedChangeListener  mListener;
+    /**
+     *  Create a new HistoryItem.
+     *  @param context  Context for this HistoryItem.
+     */
+    /* package */ HistoryItem(Context context) {
+        super(context);
+
+        mStar = (CompoundButton) findViewById(R.id.star);
+        mStar.setVisibility(View.VISIBLE);
+        mListener = new CompoundButton.OnCheckedChangeListener() {
+            public void onCheckedChanged(CompoundButton buttonView,
+                    boolean isChecked) {
+                ContentResolver cr = mContext.getContentResolver();
+                Cursor cursor = cr.query(
+                        Browser.BOOKMARKS_URI,
+                        Browser.HISTORY_PROJECTION,
+                        "url = ?",
+                        new String[] { mUrl },
+                        null);
+                boolean first = cursor.moveToFirst();
+                // Should be in the database no matter what
+                if (!first) {
+                    throw new AssertionError("URL is not in the database!");
+                }
+                if (isChecked) {
+                    // Add to bookmarks
+                    // FIXME: Share code with AddBookmarkPage.java
+                    ContentValues map = new ContentValues();
+                    map.put(Browser.BookmarkColumns.CREATED,
+                            new Date().getTime());
+                    map.put(Browser.BookmarkColumns.TITLE, getName());
+                    map.put(Browser.BookmarkColumns.BOOKMARK, 1);
+                    try {
+                        cr.update(Browser.BOOKMARKS_URI, map, 
+                                "_id = " + cursor.getInt(0), null);
+                    } catch (IllegalStateException e) {
+                        Log.e("HistoryItem", "no database!");
+                    }
+                    WebIconDatabase.getInstance().retainIconForPageUrl(mUrl);
+                    // catch IllegalStateException?
+                    Toast.makeText(mContext, R.string.added_to_bookmarks,
+                            Toast.LENGTH_LONG).show();
+                } else {
+                    // Remove from bookmarks
+                    // FIXME: This code should be shared with
+                    // BrowserBookmarksAdapter.java
+                    WebIconDatabase.getInstance().releaseIconForPageUrl(mUrl);
+                    Uri uri = ContentUris.withAppendedId(Browser.BOOKMARKS_URI,
+                            cursor.getInt(Browser.HISTORY_PROJECTION_ID_INDEX));
+                    // It is no longer a bookmark, but it is still a visited
+                    // site.
+                    ContentValues values = new ContentValues();
+                    values.put(Browser.BookmarkColumns.BOOKMARK, 0);
+                    try {
+                        cr.update(uri, values, null, null);
+                    } catch (IllegalStateException e) {
+                        Log.e("HistoryItem", "no database!");
+                    }
+                    Toast.makeText(mContext, R.string.removed_from_bookmarks,
+                            Toast.LENGTH_LONG).show();
+                }
+                cursor.deactivate();
+            }
+        };
+    }
+    
+    void copyTo(HistoryItem item) {
+        item.mTextView.setText(mTextView.getText());
+        item.mUrlText.setText(mUrlText.getText());
+        item.setIsBookmark(mStar.isChecked());
+        item.mImageView.setImageDrawable(mImageView.getDrawable());
+    }
+
+    /**
+     *  Set whether or not this represents a bookmark, and make sure the star
+     *  behaves appropriately.
+     */
+    void setIsBookmark(boolean isBookmark) {
+        mStar.setOnCheckedChangeListener(null);
+        mStar.setChecked(isBookmark);
+        mStar.setOnCheckedChangeListener(mListener);
+    }
+}
diff --git a/src/com/android/browser/ImageAdapter.java b/src/com/android/browser/ImageAdapter.java
new file mode 100644
index 0000000..b4c1209
--- /dev/null
+++ b/src/com/android/browser/ImageAdapter.java
@@ -0,0 +1,291 @@
+/*
+ * Copyright (C) 2008 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.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.database.DataSetObserver;
+import android.graphics.Color;
+import android.view.KeyEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.webkit.WebView;
+import android.widget.ImageView;
+import android.widget.ListAdapter;
+import android.widget.TextView;
+
+import java.util.ArrayList;
+
+/**
+ * Adapter used by ImageGrid.
+ */
+public class ImageAdapter implements ListAdapter {
+    
+    ArrayList<TabControl.Tab> mItems;  // Items shown in the grid
+    private ArrayList<DataSetObserver> mDataObservers; // Data change listeners
+    private Context mContext;  // Context to use to inflate views
+    private boolean mMaxedOut;
+    private ImageGrid mImageGrid;
+    private boolean mIsLive;
+    private int mTabHeight;
+
+    ImageAdapter(Context context, ImageGrid grid, boolean live) {
+        mContext = context;
+        mIsLive = live;
+        mItems = new ArrayList<TabControl.Tab>();
+        mImageGrid = grid;
+        mDataObservers = new ArrayList<DataSetObserver>();
+    }
+
+    void heightChanged(int newHeight) {
+        mTabHeight = newHeight;
+    }
+
+    /**
+     *  Whether the adapter is at its limit, determined by TabControl.MAX_TABS
+     *
+     *  @return True if the number of Tabs represented in this Adapter is at its
+     *          maximum.
+     */
+    public boolean maxedOut() {
+        return mMaxedOut;
+    }
+
+    /**
+     * Clear the internal WebViews and remove their picture listeners.
+     */
+    public void clear() {
+        for (TabControl.Tab t : mItems) {
+            clearPictureListeners(t);
+        }
+        mItems.clear();
+        notifyObservers();
+    }
+
+    private void clearPictureListeners(TabControl.Tab t) {
+        if (t.getWebView() != null) {
+            t.getWebView().setPictureListener(null);
+            if (t.getSubWebView() != null) {
+                t.getSubWebView().setPictureListener(null);
+            }
+        }
+    }
+
+    /**
+     * Add a new window web page to the grid
+     * 
+     * @param t The tab to display
+     */
+    public void add(TabControl.Tab t) {
+        if (mMaxedOut) {
+            return;
+        }
+        mItems.add(t);
+        notifyObservers();
+        if (mItems.size() == TabControl.MAX_TABS) {
+            mMaxedOut = true;
+        }
+    }
+    
+    /**
+     * Remove a window from the list. At this point, the window
+     * has already gone. It just needs to be removed from the screen
+     * 
+     * @param index window to remove
+     */
+    public void remove(int index) {
+        if (index >= 0 && index < mItems.size()) {
+            clearPictureListeners(mItems.remove(index));
+            notifyObservers();
+            mMaxedOut = false;
+        }
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.ListAdapter#areAllItemsSelectable()
+     */
+    public boolean areAllItemsEnabled() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.ListAdapter#isSelectable(int)
+     */
+    public boolean isEnabled(int position) {
+        if (position >= 0 && position <= mItems.size()) {
+            return true;
+        }
+        return false;
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#getCount()
+     */
+    public int getCount() {
+        // Include the New Window button if we have not reached the tab limit
+        if (!mMaxedOut) {
+            return mItems.size()+1;
+        }
+        return mItems.size();
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#getItem(int)
+     */
+    public Object getItem(int position) {
+        if (!mMaxedOut) {
+            if (0 == position) {
+                return null;
+            }
+            return mItems.get(position);
+        }
+        return mItems.get(position);
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#getItemId(int)
+     */
+    public long getItemId(int position) {
+        return position;
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#getView(int, android.view.View, 
+     * android.view.ViewGroup)
+     */
+    public View getView(int position, View convertView, ViewGroup parent) {
+        View v = null;
+        if (convertView != null) {
+            v = convertView;
+        } else {
+            LayoutInflater factory = LayoutInflater.from(mContext);
+            v = factory.inflate(R.layout.tabitem, null);
+        }
+        FakeWebView img = (FakeWebView) v.findViewById(R.id.icon);
+        ImageView close = (ImageView) v.findViewById(R.id.close);
+        TextView tv = (TextView) v.findViewById(R.id.label);
+
+        // position needs to be in the range of Tab indices.
+        if (!mMaxedOut) {
+            position--;
+        }
+
+        // Create the View for actual tabs
+        if (position != ImageGrid.NEW_TAB) {
+            TabControl.Tab t = mItems.get(position);
+            img.setTab(t);
+            tv.setText(t.getTitle());
+            // Do not put the 'X' if the tab picker isn't "live" (meaning the
+            // user cannot click on a tab)
+            if (!mIsLive) {
+                close.setVisibility(View.GONE);
+            } else {
+                close.setVisibility(View.VISIBLE);
+                final int pos = position;
+                close.setOnClickListener(new View.OnClickListener() {
+                        public void onClick(View v) {
+                            ImageAdapter.this.confirmClose(pos);
+                        }
+                    });
+            }
+        } else {
+            img.setBackgroundColor(Color.BLACK);
+            img.setImageResource(R.drawable.ic_new_window);
+            img.setScaleType(ImageView.ScaleType.CENTER);
+            img.setPadding(0, 0, 0, 34);
+            tv.setText(R.string.new_window);
+            close.setVisibility(View.GONE);
+        }
+        ViewGroup.LayoutParams lp = img.getLayoutParams();
+        if (lp.height != mTabHeight) {
+            lp.height = mTabHeight;
+            img.requestLayout();
+        }
+        return v;
+    }
+
+    /*
+     * Pop a confirmation dialog to the user asking if they want to close this
+     * tab.
+     */
+    private void confirmClose(final int position) {
+        final ImageGrid.Listener l = mImageGrid.getListener();
+        if (l == null) {
+            return;
+        }
+        DialogInterface.OnClickListener confirm =
+                new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog,
+                            int whichButton) {
+                        l.remove(position);
+                    }
+                };
+        new AlertDialog.Builder(mContext)
+                .setTitle(R.string.close)
+                .setIcon(android.R.drawable.ic_dialog_alert)
+                .setMessage(R.string.close_window)
+                .setPositiveButton(R.string.ok, confirm)
+                .setNegativeButton(R.string.cancel, null)
+                .show();
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#registerDataSetObserver(android.database.DataSetObserver)
+     */
+    public void registerDataSetObserver(DataSetObserver observer) {
+        mDataObservers.add(observer);
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#hasStableIds()
+     */
+    public boolean hasStableIds() {
+        return true;
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.Adapter#unregisterDataSetObserver(android.database.DataSetObserver)
+     */
+    public void unregisterDataSetObserver(DataSetObserver observer) {
+        mDataObservers.remove(observer);
+    }
+
+    /**
+     * Notify all the observers that a change has happened.
+     */
+    void notifyObservers() {
+        for (DataSetObserver observer : mDataObservers) {
+            observer.onChanged();
+        }
+    }
+
+    public int getItemViewType(int position) {
+        return 0;
+    }
+
+    public int getViewTypeCount() {
+        return 1;
+    }
+
+    public boolean isEmpty() {
+        return getCount() == 0;
+    }
+}
diff --git a/src/com/android/browser/ImageGrid.java b/src/com/android/browser/ImageGrid.java
new file mode 100644
index 0000000..9eccb16
--- /dev/null
+++ b/src/com/android/browser/ImageGrid.java
@@ -0,0 +1,233 @@
+/*
+ * Copyright (C) 2008 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.Config;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.KeyEvent;
+import android.view.MenuInflater;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnCreateContextMenuListener;
+import android.webkit.WebView;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemClickListener;
+import android.widget.GridView;
+
+/**
+ * This class implements a Grid layout of Views for the Tab picker.
+ */
+class ImageGrid extends GridView implements OnItemClickListener, 
+        OnCreateContextMenuListener  {
+    
+    private Listener     mListener;
+    private ImageAdapter mAdapter;
+    private boolean      mIsLive;
+    private static final int SPACING = 10;
+    public static final int CANCEL  = -99;
+    public static final int NEW_TAB = -1;
+
+    /**
+     * Constructor
+     * @param context Context to use when inflating resources.
+     * @param live  TRUE if the view can accept touch or click
+     * @param l     Listener to respond to clicks etc.
+     */
+    public ImageGrid(Context context, boolean live, Listener l) {
+        super(context);
+
+        mIsLive = live;
+        if (live) {
+            setFocusable(true);
+            setFocusableInTouchMode(true);
+            setOnItemClickListener(this);
+            setOnCreateContextMenuListener(this);
+        }
+        mListener = l;
+
+        mAdapter = new ImageAdapter(context, this, live);
+        setAdapter(mAdapter);
+
+        setBackgroundColor(0xFF000000);
+
+        setVerticalSpacing(SPACING);
+        setHorizontalSpacing(SPACING);
+        setNumColumns(2);
+        setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
+        setSelector(android.R.drawable.gallery_thumb);
+    }
+
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        // We always consume the BACK key even if mListener is null or the
+        // ImageGrid is not "live." This prevents crashes during tab animations
+        // if the user presses BACK.
+        if ((event.getAction() == KeyEvent.ACTION_DOWN) &&
+                (event.getKeyCode() == KeyEvent.KEYCODE_BACK)) {
+            if (mListener != null && mIsLive) {
+                mListener.onClick(CANCEL);
+                invalidate();
+            }
+            return true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+    
+    /**
+     * Called by BrowserActivity to add a new window to the tab picker.
+     * This does not happen dynamically, this only happens during view
+     * setup.
+     * 
+     * @param v Webview of the tab to add
+     * @param name Web page title
+     * @param url URL of the webpage
+     */
+    public void add(TabControl.Tab t) {
+        mAdapter.add(t);
+    }
+
+    /**
+     * Called by BrowserActivity when a window has been removed from the
+     * tab list.
+     * 
+     * @param index Window to remove, from 0 to MAX_TABS-1
+     */
+    public void remove(int index) {
+        if (Config.DEBUG && (index < 0 || index >= TabControl.MAX_TABS)) {
+            throw new AssertionError();
+        }
+        mAdapter.remove(index);
+    }
+
+    /**
+     * Request focus to initially set to a particular tab. 
+     *
+     * @param startingIndex This is a Tab index from 0 - MAX_TABS-1 and does not
+     *                      include the "New Tab" cell.
+     */
+    public void setCurrentIndex(int startingIndex) {
+        if (!mAdapter.maxedOut()) {
+            startingIndex++;
+        }
+        setSelection(startingIndex);
+    }
+
+    public Listener getListener() {
+        return mListener;
+    }
+
+    public void setListener(Listener l) {
+        mListener = l;
+    }
+
+    /**
+     * Return true if the ImageGrid is live. This means that tabs can be chosen
+     * and the menu can be invoked.
+     */
+    public boolean isLive() {
+        return mIsLive;
+    }
+
+    /**
+     * Do some internal cleanup of the ImageGrid's adapter.
+     */
+    public void clear() {
+        mAdapter.clear();
+    }
+
+    /* (non-Javadoc)
+     * @see android.widget.AdapterView.OnItemClickListener#onItemClick(android.widget.AdapterView, android.view.View, int, long)
+     */
+    public void onItemClick(AdapterView parent, View v, int position, long id) {
+        if (!mAdapter.maxedOut()) {
+            position--;
+        }
+        // Position will be -1 for the "New Tab" cell.
+        if (mListener != null) {
+            mListener.onClick(position);
+        }
+    }
+    
+    /* (non-Javadoc)
+     * @see android.view.View.OnCreateContextMenuListener#onCreateContextMenu(android.view.ContextMenu, android.view.View, java.lang.Object)
+     */
+    public void onCreateContextMenu(ContextMenu menu, View v, 
+            ContextMenuInfo menuInfo) {
+        // Do not create the context menu if there is no listener or the Tab
+        // overview is not "live."
+        if (mListener == null || !mIsLive) {
+            return;
+        }
+        AdapterView.AdapterContextMenuInfo info = 
+                (AdapterView.AdapterContextMenuInfo) menuInfo;
+        boolean maxed = mAdapter.maxedOut();
+        if (info.position > 0 || maxed) {
+            MenuInflater inflater = new MenuInflater(mContext);
+            inflater.inflate(R.menu.tabscontext, menu);
+            int position = info.position;
+            if (!maxed) {
+                position--;
+            }
+            menu.setHeaderTitle(mAdapter.mItems.get(position).getTitle());
+        }
+    }
+
+    // convert a context menu position to an actual tab position. Since context
+    // menus are not created for the "New Tab" cell, this will always return a
+    // valid tab position.
+    public int getContextMenuPosition(MenuItem menu) {
+        AdapterView.AdapterContextMenuInfo info =
+                (AdapterView.AdapterContextMenuInfo) menu.getMenuInfo();
+        int pos = info.position;
+        if (!mAdapter.maxedOut()) {
+            pos--;
+        }
+        return pos;
+    }
+    
+    @Override
+    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
+        // Called when our orientation changes. Tell the adapter about the new
+        // size. Compute the individual tab height by taking the grid height
+        // and subtracting the SPACING. Then subtract the list padding twice
+        // (once for each tab on screen) and divide the remaining height by 2.
+        int tabHeight = (h - SPACING
+                - 2 * (getListPaddingTop() + getListPaddingBottom())) / 2;
+        mAdapter.heightChanged(tabHeight);
+        super.onSizeChanged(w, h, oldw, oldh);
+    }
+
+    /**
+     * Listener to be notified by behavior of ImageGrid.
+     */
+    public interface Listener {
+        /**
+         * Called when enter is pressed on the list.
+         * @param position  The index of the selected image when
+         *                  enter is pressed.
+         */
+        void onClick(int position);
+
+        /**
+         * Called when remove is called on the grid.
+         */
+        void remove(int position);
+    }
+
+}
diff --git a/src/com/android/browser/KeyTracker.java b/src/com/android/browser/KeyTracker.java
new file mode 100644
index 0000000..344e4f8
--- /dev/null
+++ b/src/com/android/browser/KeyTracker.java
@@ -0,0 +1,107 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.view.KeyEvent;
+import android.view.ViewConfiguration;
+
+class KeyTracker {
+
+    public enum Stage {
+        DOWN,           //!< the key has just been pressed
+        SHORT_REPEAT,   //!< repeated key, but duration is under the long-press threshold
+        LONG_REPEAT,    //!< repeated key, but duration is over the long-press threshold
+        UP              //!< the key is being released
+    }
+    
+    public enum State {
+        KEEP_TRACKING,  //!< return this to continue to track the key
+        DONE_TRACKING,  //!< return this if you handled the key, but need not track it anymore
+        NOT_TRACKING    //!< return this if you will not handle this key
+    }
+    
+    public interface OnKeyTracker {
+
+        /** Called whenever there is a key event [down, short/long repeat, up]
+            @param keyCode  The current keyCode (see KeyEvent class)
+            @param msg      The message associated with the keyCode
+            @maram stage    The state the key press is in [down, short/long repeat, up]
+            @param duration The number of milliseconds since this key was initially pressed
+            @return your state after seeing the key. If you return DONE_TRACKING or NOT_TRACKING,
+                    you will not be called again for the lifetime of this key event.
+        */
+        public State onKeyTracker(int keyCode, KeyEvent event, Stage stage, int duration);
+    }
+    
+    public KeyTracker(OnKeyTracker tracker) {
+        mTracker = tracker;
+    }
+    
+    public boolean doKeyDown(int keyCode, KeyEvent event) {
+        long now = System.currentTimeMillis();
+        Stage stage = null;
+
+        // check if its a new/different key
+        if (mKeyCode != keyCode || event.getRepeatCount() == 0) {
+            mKeyCode = keyCode;
+            mStartMS = now;
+            stage = Stage.DOWN;
+        }
+        else if (mState == State.KEEP_TRACKING) {
+            stage = (now - mStartMS) >= LONG_PRESS_DURATION_MS ? Stage.LONG_REPEAT : Stage.SHORT_REPEAT;
+        }
+
+        if (stage != null) {
+            mEvent = event;        
+            callTracker(stage, now);
+        }
+
+        return mState != State.NOT_TRACKING;
+    }
+    
+    public boolean doKeyUp(int keyCode, KeyEvent event) {
+        boolean handled = false;
+
+        if (mState == State.KEEP_TRACKING && mKeyCode == keyCode) {
+            mEvent = event;
+            callTracker(Stage.UP, System.currentTimeMillis());
+            handled = mState != State.NOT_TRACKING;
+        }
+        mKeyCode = NOT_A_KEYCODE;
+        return handled;
+    }
+    
+    private void callTracker(Stage stage, long now) {
+        mState = mTracker.onKeyTracker(mKeyCode, mEvent, stage, (int)(now - mStartMS));
+    }
+    
+    private void dump() {
+        System.out.println(" key=" + mKeyCode + " dur=" + (System.currentTimeMillis() - mStartMS) +
+                            " state=" + mState);
+    }
+
+    private int             mKeyCode = NOT_A_KEYCODE;
+    private KeyEvent        mEvent;
+    private long            mStartMS;
+    private State           mState;
+    private OnKeyTracker    mTracker;
+
+    private static final int LONG_PRESS_DURATION_MS = 
+            ViewConfiguration.getLongPressTimeout();
+    private static final int NOT_A_KEYCODE = -123456;
+}
+
diff --git a/src/com/android/browser/MostVisitedActivity.java b/src/com/android/browser/MostVisitedActivity.java
new file mode 100644
index 0000000..704ee27
--- /dev/null
+++ b/src/com/android/browser/MostVisitedActivity.java
@@ -0,0 +1,199 @@
+/*
+ * 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;
+
+import android.app.Activity;
+import android.app.ListActivity;
+import android.content.Intent;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+import android.os.Handler;
+import android.provider.Browser;
+import android.webkit.WebIconDatabase.IconListener;
+import android.widget.ListAdapter;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+import android.widget.TextView;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.ViewGroup.LayoutParams;
+
+import java.util.Vector;
+
+public class MostVisitedActivity extends ListActivity {
+
+    private MyAdapter   mAdapter;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        mAdapter = new MyAdapter();
+        CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
+                .addListener(new IconReceiver());
+        setListAdapter(mAdapter);
+        ListView list = getListView();
+        LayoutInflater factory = LayoutInflater.from(this);
+        View v = factory.inflate(R.layout.empty_history, null);
+        addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
+                LayoutParams.FILL_PARENT));
+        list.setEmptyView(v);
+    }
+
+    private class IconReceiver implements IconListener {
+        public void onReceivedIcon(String url, Bitmap icon) {
+            setListAdapter(mAdapter);
+        }
+    }
+
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        TextView tv = (TextView) v.findViewById(R.id.url);
+        String url = tv.getText().toString();
+        loadUrl(url, false);
+    }
+
+    private void loadUrl(String url, boolean newWindow) {
+        Intent intent = new Intent().setAction(url);
+        if (newWindow) {
+            Bundle b = new Bundle();
+            b.putBoolean("new_window", true);
+            intent.putExtras(b);
+        }
+        setResultToParent(RESULT_OK, intent);
+        finish();
+    }
+
+    private class MyAdapter implements ListAdapter {
+        private Vector<DataSetObserver> mObservers;
+        private Cursor mCursor;
+        // These correspond with projection below.
+        private final int mUrlIndex = 0;
+        private final int mTitleIndex = 1;
+        private final int mBookmarkIndex = 2;
+
+        MyAdapter() {
+            mObservers = new Vector<DataSetObserver>();
+            String[] projection = new String[] {
+                    Browser.BookmarkColumns.URL,
+                    Browser.BookmarkColumns.TITLE,
+                    Browser.BookmarkColumns.BOOKMARK };
+            String whereClause = Browser.BookmarkColumns.VISITS + " != 0";
+            String orderBy = Browser.BookmarkColumns.VISITS + " DESC";
+            mCursor = managedQuery(Browser.BOOKMARKS_URI, projection,
+                    whereClause, null, orderBy);
+            mCursor.registerContentObserver(new ChangeObserver());
+        }
+
+        private class ChangeObserver extends ContentObserver {
+            public ChangeObserver() {
+                super(new Handler());
+            }
+
+            @Override
+            public boolean deliverSelfNotifications() {
+                return true;
+            }
+
+            @Override
+            public void onChange(boolean selfChange) {
+                MyAdapter.this.refreshData();
+            }
+        }
+
+        void refreshData() {
+            mCursor.requery();
+            for (DataSetObserver o : mObservers) {
+                o.onChanged();
+            }
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            HistoryItem item;
+            if (null == convertView) {
+                item = new HistoryItem(MostVisitedActivity.this);
+            } else {
+                item = (HistoryItem) convertView;
+            }
+            mCursor.moveToPosition(position);
+            item.setName(mCursor.getString(mTitleIndex));
+            String url = mCursor.getString(mUrlIndex);
+            item.setUrl(url);
+            item.setFavicon(CombinedBookmarkHistoryActivity.getIconListenerSet(
+                    getContentResolver()).getFavicon(url));
+            item.setIsBookmark(1 == mCursor.getInt(mBookmarkIndex));
+            return item;
+        }
+
+        public boolean areAllItemsEnabled() {
+            return true;
+        }
+
+        public boolean isEnabled(int position) {
+            return true;
+        }
+
+        public int getCount() {
+            return mCursor.getCount();
+        }
+
+        public Object getItem(int position) {
+            return null;
+        }
+
+        public long getItemId(int position) {
+            return position;
+        }
+
+        // Always a HistoryItem
+        public int getItemViewType(int position) {
+            return 0;
+        }
+
+        public int getViewTypeCount() {
+            return 1;
+        }
+
+        public boolean hasStableIds() {
+            return true;
+        }
+
+        public void registerDataSetObserver(DataSetObserver observer) {
+            mObservers.add(observer);
+        }
+
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+            mObservers.remove(observer);
+        }
+
+        public boolean isEmpty() {
+            return getCount() == 0;
+        }
+    }
+
+    // This Activity is generally a sub-Activity of CombinedHistoryActivity. In
+    // that situation, we need to pass our result code up to our parent.
+    // However, if someone calls this Activity directly, then this has no
+    // parent, and it needs to set it on itself.
+    private void setResultToParent(int resultCode, Intent data) {
+        Activity a = getParent() == null ? this : getParent();
+        a.setResult(resultCode, data);
+    }
+}
+
diff --git a/src/com/android/browser/TabControl.java b/src/com/android/browser/TabControl.java
new file mode 100644
index 0000000..2f39302
--- /dev/null
+++ b/src/com/android/browser/TabControl.java
@@ -0,0 +1,937 @@
+/*
+ * Copyright (C) 2007 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.net.http.SslError;
+import android.os.Bundle;
+import android.os.Message;
+import android.util.Config;
+import android.util.Log;
+import android.view.Gravity;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.View.OnClickListener;
+import android.webkit.HttpAuthHandler;
+import android.webkit.JsPromptResult;
+import android.webkit.JsResult;
+import android.webkit.SslErrorHandler;
+import android.webkit.WebBackForwardList;
+import android.webkit.WebChromeClient;
+import android.webkit.WebHistoryItem;
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.widget.FrameLayout;
+import android.widget.ImageButton;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.Vector;
+
+class TabControl {
+    // Log Tag
+    private static final String LOGTAG = "TabControl";
+    // Maximum number of tabs.
+    static final int MAX_TABS = 8;
+    // Static instance of an empty callback.
+    private static final WebViewClient mEmptyClient =
+            new WebViewClient();
+    // Instance of BackgroundChromeClient for background tabs.
+    private final BackgroundChromeClient mBackgroundChromeClient =
+            new BackgroundChromeClient();
+    // Private array of WebViews that are used as tabs.
+    private ArrayList<Tab> mTabs = new ArrayList<Tab>(MAX_TABS);
+    // Queue of most recently viewed tabs.
+    private ArrayList<Tab> mTabQueue = new ArrayList<Tab>(MAX_TABS);
+    // Current position in mTabs.
+    private int mCurrentTab = -1;
+    // A private instance of BrowserActivity to interface with when adding and
+    // switching between tabs.
+    private final BrowserActivity mActivity;
+    // Inflation service for making subwindows.
+    private final LayoutInflater mInflateService;
+    // Subclass of WebViewClient used in subwindows to notify the main
+    // WebViewClient of certain WebView activities.
+    private class SubWindowClient extends WebViewClient {
+        // The main WebViewClient.
+        private final WebViewClient mClient;
+
+        SubWindowClient(WebViewClient client) {
+            mClient = client;
+        }
+        @Override
+        public void doUpdateVisitedHistory(WebView view, String url,
+                boolean isReload) {
+            mClient.doUpdateVisitedHistory(view, url, isReload);
+        }
+        @Override
+        public boolean shouldOverrideUrlLoading(WebView view, String url) {
+            return mClient.shouldOverrideUrlLoading(view, url);
+        }
+        @Override
+        public void onReceivedSslError(WebView view, SslErrorHandler handler,
+                SslError error) {
+            mClient.onReceivedSslError(view, handler, error);
+        }
+        @Override
+        public void onReceivedHttpAuthRequest(WebView view,
+                HttpAuthHandler handler, String host, String realm) {
+            mClient.onReceivedHttpAuthRequest(view, handler, host, realm);
+        }
+        @Override
+        public void onFormResubmission(WebView view, Message dontResend,
+                Message resend) {
+            mClient.onFormResubmission(view, dontResend, resend);
+        }
+        @Override
+        public void onReceivedError(WebView view, int errorCode,
+                String description, String failingUrl) {
+            mClient.onReceivedError(view, errorCode, description, failingUrl);
+        }
+    }
+    // Subclass of WebChromeClient to display javascript dialogs.
+    private class SubWindowChromeClient extends WebChromeClient {
+        // This subwindow's tab.
+        private final Tab mTab;
+        // The main WebChromeClient.
+        private final WebChromeClient mClient;
+
+        SubWindowChromeClient(Tab t, WebChromeClient client) {
+            mTab = t;
+            mClient = client;
+        }
+        @Override
+        public void onProgressChanged(WebView view, int newProgress) {
+            mClient.onProgressChanged(view, newProgress);
+        }
+        @Override
+        public boolean onCreateWindow(WebView view, boolean dialog,
+                boolean userGesture, android.os.Message resultMsg) {
+            return mClient.onCreateWindow(view, dialog, userGesture, resultMsg);
+        }
+        @Override
+        public void onCloseWindow(WebView window) {
+            if (Config.DEBUG && window != mTab.mSubView) {
+                throw new AssertionError("Can't close the window");
+            }
+            mActivity.dismissSubWindow(mTab);
+        }
+    }
+    // Background WebChromeClient for focusing tabs
+    private class BackgroundChromeClient extends WebChromeClient {
+        @Override
+        public void onRequestFocus(WebView view) {
+            Tab t = getTabFromView(view);
+            if (t != getCurrentTab()) {
+                mActivity.showTab(t);
+            }
+        }
+    }
+
+    /**
+     * Private class for maintaining Tabs with a main WebView and a subwindow.
+     */
+    public class Tab {
+        // Main WebView
+        private WebView mMainView;
+        // Subwindow WebView
+        private WebView mSubView;
+        // Subwindow container
+        private View mSubViewContainer;
+        // Subwindow callback
+        private SubWindowClient mSubViewClient;
+        // Subwindow chrome callback
+        private SubWindowChromeClient mSubViewChromeClient;
+        // Saved bundle for when we are running low on memory. It contains the
+        // information needed to restore the WebView if the user goes back to
+        // the tab.
+        private Bundle mSavedState;
+        // Extra saved information for displaying the tab in the picker.
+        private String mUrl;
+        private String mTitle;
+ 
+        // Parent Tab. This is the Tab that created this Tab, or null
+        // if the Tab was created by the UI
+        private Tab mParentTab;
+        // Tab that constructed by this Tab. This is used when this
+        // Tab is destroyed, it clears all mParentTab values in the 
+        // children.
+        private Vector<Tab> mChildTabs;
+
+        private Boolean mCloseOnExit;
+
+        // Construct a new tab
+        private Tab(WebView w, boolean closeOnExit) {
+            mMainView = w;
+            mCloseOnExit = closeOnExit;
+        }
+
+        /**
+         * Return the top window of this tab; either the subwindow if it is not
+         * null or the main window.
+         * @return The top window of this tab.
+         */
+        public WebView getTopWindow() {
+            if (mSubView != null) {
+                return mSubView;
+            }
+            return mMainView;
+        }
+
+        /**
+         * Return the main window of this tab. Note: if a tab is freed in the
+         * background, this can return null. It is only guaranteed to be 
+         * non-null for the current tab.
+         * @return The main WebView of this tab.
+         */
+        public WebView getWebView() {
+            return mMainView;
+        }
+
+        /**
+         * Return the subwindow of this tab or null if there is no subwindow.
+         * @return The subwindow of this tab or null.
+         */
+        public WebView getSubWebView() {
+            return mSubView;
+        }
+
+        /**
+         * Return the subwindow container of this tab or null if there is no
+         * subwindow.
+         * @return The subwindow's container View.
+         */
+        public View getSubWebViewContainer() {
+            return mSubViewContainer;
+        }
+
+        /**
+         * Get the url of this tab.  Valid after calling populatePickerData, but
+         * before calling wipePickerData, or if the webview has been destroyed.
+         * 
+         * @return The WebView's url or null.
+         */
+        public String getUrl() {
+            return mUrl;
+        }
+
+        /**
+         * Get the title of this tab.  Valid after calling populatePickerData, 
+         * but before calling wipePickerData, or if the webview has been 
+         * destroyed.  If the url has no title, use the url instead.
+         * 
+         * @return The WebView's title (or url) or null.
+         */
+        public String getTitle() {
+            return mTitle;
+        }
+
+        private void setParentTab(Tab parent) {
+            mParentTab = parent;
+            // This tab may have been freed due to low memory. If that is the
+            // case, the parent tab index is already saved. If we are changing
+            // that index (most likely due to removing the parent tab) we must
+            // update the parent tab index in the saved Bundle.
+            if (mSavedState != null) {
+                if (parent == null) {
+                    mSavedState.remove(PARENTTAB);
+                } else {
+                    mSavedState.putInt(PARENTTAB, getTabIndex(parent));
+                }
+            }
+        }
+        
+        /**
+         * When a Tab is created through the content of another Tab, then 
+         * we associate the Tabs. 
+         * @param child the Tab that was created from this Tab
+         */
+        public void addChildTab(Tab child) {
+            if (mChildTabs == null) {
+                mChildTabs = new Vector<Tab>();
+            }
+            mChildTabs.add(child);
+            child.setParentTab(this);
+        }
+        
+        private void removeFromTree() {
+            // detach the children
+            if (mChildTabs != null) {
+                for(Tab t : mChildTabs) {
+                    t.setParentTab(null);
+                }
+            }
+            
+            // Find myself in my parent list
+            if (mParentTab != null) {
+                mParentTab.mChildTabs.remove(this);
+            }
+        }
+        
+        /**
+         * If this Tab was created through another Tab, then this method
+         * returns that Tab.
+         * @return the Tab parent or null
+         */
+        public Tab getParentTab() {
+            return mParentTab;
+        }
+
+        /**
+         * Return whether this tab should be closed when it is backing out of
+         * the first page.
+         * @return TRUE if this tab should be closed when exit.
+         */
+        public boolean closeOnExit() {
+            return mCloseOnExit;
+        }
+    };
+
+    // Directory to store thumbnails for each WebView.
+    private final File mThumbnailDir;
+
+    /**
+     * Construct a new TabControl object that interfaces with the given
+     * BrowserActivity instance.
+     * @param activity A BrowserActivity instance that TabControl will interface
+     *                 with.
+     */
+    TabControl(BrowserActivity activity) {
+        mActivity = activity;
+        mInflateService =
+                ((LayoutInflater) activity.getSystemService(
+                        Context.LAYOUT_INFLATER_SERVICE));
+        mThumbnailDir = activity.getDir("thumbnails", 0);
+    }
+
+    File getThumbnailDir() {
+        return mThumbnailDir;
+    }
+
+    BrowserActivity getBrowserActivity() {
+        return mActivity;
+    }
+
+    /**
+     * Return the current tab's main WebView. This will always return the main
+     * WebView for a given tab and not a subwindow.
+     * @return The current tab's WebView.
+     */
+    WebView getCurrentWebView() {
+        Tab t = getTab(mCurrentTab);
+        if (t == null) {
+            return null;
+        }
+        return t.mMainView;
+    }
+
+    /**
+     * Return the current tab's top-level WebView. This can return a subwindow
+     * if one exists.
+     * @return The top-level WebView of the current tab.
+     */
+    WebView getCurrentTopWebView() {
+        Tab t = getTab(mCurrentTab);
+        if (t == null) {
+            return null;
+        }
+        return t.mSubView != null ? t.mSubView : t.mMainView;
+    }
+
+    /**
+     * Return the current tab's subwindow if it exists.
+     * @return The subwindow of the current tab or null if it doesn't exist.
+     */
+    WebView getCurrentSubWindow() {
+        Tab t = getTab(mCurrentTab);
+        if (t == null) {
+            return null;
+        }
+        return t.mSubView;
+    }
+
+    /**
+     * Return the tab at the specified index.
+     * @return The Tab for the specified index or null if the tab does not
+     *         exist.
+     */
+    Tab getTab(int index) {
+        if (index >= 0 && index < mTabs.size()) {
+            return mTabs.get(index);
+        }
+        return null;
+    }
+
+    /**
+     * Return the current tab.
+     * @return The current tab.
+     */
+    Tab getCurrentTab() {
+        return getTab(mCurrentTab);
+    }
+
+    /**
+     * Return the current tab index.
+     * @return The current tab index
+     */
+    int getCurrentIndex() {
+        return mCurrentTab;
+    }
+    
+    /**
+     * Given a Tab, find it's index
+     * @param Tab to find
+     * @return index of Tab or -1 if not found
+     */
+    int getTabIndex(Tab tab) {
+        return mTabs.indexOf(tab);
+    }
+
+    /**
+     * Create a new tab and display the new tab immediately.
+     * @return The newly createTab or null if we have reached the maximum
+     *         number of open tabs.
+     */
+    Tab createNewTab(boolean closeOnExit) {
+        int size = mTabs.size();
+        // Return false if we have maxed out on tabs
+        if (MAX_TABS == size) {
+            return null;
+        }
+        // Create a new WebView
+        WebView w = new WebView(mActivity);
+        w.setMapTrackballToArrowKeys(false); // use trackball directly
+        // Add this WebView to the settings observer list and update the
+        // settings
+        final BrowserSettings s = BrowserSettings.getInstance();
+        s.addObserver(w.getSettings()).update(s, null);
+        // Create a new tab and add it to the tab list
+        Tab t = new Tab(w, closeOnExit);
+        mTabs.add(t);
+        return t;
+    }
+
+    /**
+     * Remove the tab from the list. If the tab is the current tab shown, the
+     * last created tab will be shown.
+     * @param t The tab to be removed.
+     */
+    boolean removeTab(Tab t) {
+        if (t == null) {
+            return false;
+        }
+        // Only remove the tab if it is the current one.
+        if (getCurrentTab() == t) {
+            putTabInBackground(t);
+        }
+
+        // Only destroy the WebView if it still exists.
+        if (t.mMainView != null) {
+            // Take down the sub window.
+            dismissSubWindow(t);
+            // Remove the WebView's settings from the BrowserSettings list of
+            // observers.
+            BrowserSettings.getInstance().deleteObserver(
+                    t.mMainView.getSettings());
+            // Destroy the main view and subview
+            t.mMainView.destroy();
+            t.mMainView = null;
+        }
+        // clear it's references to parent and children
+        t.removeFromTree();
+        
+        // Remove it from our list of tabs.
+        mTabs.remove(t);
+
+        // The tab indices have shifted, update all the saved state so we point
+        // to the correct index.
+        for (Tab tab : mTabs) {
+            if (tab.mChildTabs != null) {
+                for (Tab child : tab.mChildTabs) {
+                    child.setParentTab(tab);
+                }
+            }
+        }
+
+
+        // This tab may have been pushed in to the background and then closed.
+        // If the saved state contains a picture file, delete the file.
+        if (t.mSavedState != null) {
+            if (t.mSavedState.containsKey("picture")) {
+                new File(t.mSavedState.getString("picture")).delete();
+            }
+        }
+
+        // Remove it from the queue of viewed tabs.
+        mTabQueue.remove(t);
+        mCurrentTab = -1;
+        return true;
+    }
+
+    /**
+     * Clear the back/forward list for all the current tabs.
+     */
+    void clearHistory() {
+        int size = getTabCount();
+        for (int i = 0; i < size; i++) {
+            Tab t = mTabs.get(i);
+            // TODO: if a tab is freed due to low memory, its history is not
+            // cleared here.
+            if (t.mMainView != null) {
+                t.mMainView.clearHistory();
+            }
+            if (t.mSubView != null) {
+                t.mSubView.clearHistory();
+            }
+        }
+    }
+
+    /**
+     * Destroy all the tabs and subwindows
+     */
+    void destroy() {
+        BrowserSettings s = BrowserSettings.getInstance();
+        for (Tab t : mTabs) {
+            if (t.mMainView != null) {
+                dismissSubWindow(t);
+                s.deleteObserver(t.mMainView.getSettings());
+                t.mMainView.destroy();
+                t.mMainView = null;
+            }
+        }
+        mTabs.clear();
+        mTabQueue.clear();
+    }
+
+    /**
+     * Returns the number of tabs created.
+     * @return The number of tabs created.
+     */
+    int getTabCount() {
+        return mTabs.size();
+    }
+
+    // Used for saving and restoring each Tab
+    private static final String WEBVIEW = "webview";
+    private static final String NUMTABS = "numTabs";
+    private static final String CURRTAB = "currentTab";
+    private static final String CURRURL = "currentUrl";
+    private static final String CURRTITLE = "currentTitle";
+    private static final String CLOSEONEXIT = "closeonexit";
+    private static final String PARENTTAB = "parentTab";
+
+    /**
+     * Save the state of all the Tabs.
+     * @param outState The Bundle to save the state to.
+     */
+    void saveState(Bundle outState) {
+        final int numTabs = getTabCount();
+        outState.putInt(NUMTABS, numTabs);
+        final int index = getCurrentIndex();
+        outState.putInt(CURRTAB, (index >= 0 && index < numTabs) ? index : 0);
+        for (int i = 0; i < numTabs; i++) {
+            final Tab t = getTab(i);
+            if (saveState(t)) {
+                outState.putBundle(WEBVIEW + i, t.mSavedState);
+            }
+        }
+    }
+
+    /**
+     * Restore the state of all the tabs.
+     * @param inState The saved state of all the tabs.
+     * @return True if there were previous tabs that were restored. False if
+     *         there was no saved state or restoring the state failed.
+     */
+    boolean restoreState(Bundle inState) {
+        final int numTabs = (inState == null)
+                ? -1 : inState.getInt(NUMTABS, -1);
+        if (numTabs == -1) {
+            return false;
+        } else {
+            final int currentTab = inState.getInt(CURRTAB, -1);
+            for (int i = 0; i < numTabs; i++) {
+                if (i == currentTab) {
+                    Tab t = createNewTab(false);
+                    // Me must set the current tab before restoring the state
+                    // so that all the client classes are set.
+                    setCurrentTab(t);
+                    if (!restoreState(inState.getBundle(WEBVIEW + i), t)) {
+                        Log.w(LOGTAG, "Fail in restoreState, load home page.");
+                        t.mMainView.loadUrl(BrowserSettings.getInstance()
+                                .getHomePage());
+                    }
+                } else {
+                    // Create a new tab and don't restore the state yet, add it
+                    // to the tab list
+                    Tab t = new Tab(null, false);
+                    t.mSavedState = inState.getBundle(WEBVIEW + i);
+                    if (t.mSavedState != null) {
+                        t.mUrl = t.mSavedState.getString(CURRURL);
+                        t.mTitle = t.mSavedState.getString(CURRTITLE);
+                    }
+                    mTabs.add(t);
+                    mTabQueue.add(t);
+                }
+            }
+            // Rebuild the tree of tabs. Do this after all tabs have been
+            // created/restored so that the parent tab exists.
+            for (int i = 0; i < numTabs; i++) {
+                final Bundle b = inState.getBundle(WEBVIEW + i);
+                final Tab t = getTab(i);
+                if (b != null && t != null) {
+                    final int parentIndex = b.getInt(PARENTTAB, -1);
+                    if (parentIndex != -1) {
+                        final Tab parent = getTab(parentIndex);
+                        if (parent != null) {
+                            parent.addChildTab(t);
+                        }
+                    }
+                }
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Free the memory in this order, 1) free the background tab; 2) free the
+     * WebView cache;
+     */
+    void freeMemory() {
+        // free the least frequently used background tab
+        Tab t = getLeastUsedTab();
+        if (t != null) {
+            Log.w(LOGTAG, "Free a tab in the browser");
+            freeTab(t);
+            // force a gc
+            System.gc();
+            return;
+        }
+
+        // free the WebView cache
+        Log.w(LOGTAG, "Free WebView cache");
+        WebView view = getCurrentWebView();
+        if (view != null) {
+            view.clearCache(false);
+        }
+        // force a gc
+        System.gc();
+    }
+
+    private Tab getLeastUsedTab() {
+        // Don't do anything if we only have 1 tab.
+        if (getTabCount() == 1) {
+            return null;
+        }
+
+        // Rip through the queue starting at the beginning and teardown the
+        // next available tab.
+        Tab t = null;
+        int i = 0;
+        final int queueSize = mTabQueue.size();
+        if (queueSize == 0) {
+            return null;
+        }
+        do {
+            t = mTabQueue.get(i++);
+        } while (i < queueSize && t != null && t.mMainView == null);
+
+        // Don't do anything if the last remaining tab is the current one.
+        if (t == getCurrentTab()) {
+            return null;
+        }
+
+        return t;
+    }
+
+    private void freeTab(Tab t) {
+        // Store the WebView's state.
+        saveState(t);
+
+        // Tear down the tab.
+        dismissSubWindow(t);
+        // Remove the WebView's settings from the BrowserSettings list of
+        // observers.
+        BrowserSettings.getInstance().deleteObserver(t.mMainView.getSettings());
+        t.mMainView.destroy();
+        t.mMainView = null;
+    }
+
+    /**
+     * Create a new subwindow unless a subwindow already exists.
+     * @return True if a new subwindow was created. False if one already exists.
+     */
+    void createSubWindow() {
+        Tab t = getTab(mCurrentTab);
+        if (t != null && t.mSubView == null) {
+            final View v = mInflateService.inflate(R.layout.browser_subwindow, null);
+            final WebView w = (WebView) v.findViewById(R.id.webview);
+            w.setMapTrackballToArrowKeys(false); // use trackball directly
+            final SubWindowClient subClient =
+                    new SubWindowClient(mActivity.getWebViewClient());
+            final SubWindowChromeClient subChromeClient =
+                    new SubWindowChromeClient(t,
+                            mActivity.getWebChromeClient());
+            w.setWebViewClient(subClient);
+            w.setWebChromeClient(subChromeClient);
+            w.setDownloadListener(mActivity);
+            w.setOnCreateContextMenuListener(mActivity);
+            final BrowserSettings s = BrowserSettings.getInstance();
+            s.addObserver(w.getSettings()).update(s, null);
+            t.mSubView = w;
+            t.mSubViewClient = subClient;
+            t.mSubViewChromeClient = subChromeClient;
+            // FIXME: I really hate having to know the name of the view
+            // containing the webview.
+            t.mSubViewContainer = v.findViewById(R.id.subwindow_container);
+            final ImageButton cancel =
+                    (ImageButton) v.findViewById(R.id.subwindow_close);
+            cancel.setOnClickListener(new OnClickListener() {
+                    public void onClick(View v) {
+                        subChromeClient.onCloseWindow(w);
+                    }
+                });
+        }
+    }
+
+    /**
+     * Show the tab that contains the given WebView.
+     * @param view The WebView used to find the tab.
+     */
+    Tab getTabFromView(WebView view) {
+        final int size = getTabCount();
+        for (int i = 0; i < size; i++) {
+            final Tab t = getTab(i);
+            if (t.mSubView == view || t.mMainView == view) {
+                return t;
+            }
+        }
+        return null;
+    }
+
+    /**
+     * Put the current tab in the background and set newTab as the current tab.
+     * @param newTab The new tab. If newTab is null, the current tab is not
+     *               set.
+     */
+    boolean setCurrentTab(Tab newTab) {
+        Tab current = getTab(mCurrentTab);
+        if (current == newTab) {
+            return true;
+        }
+        if (current != null) {
+            // Remove the current WebView and the container of the subwindow
+            putTabInBackground(current);
+        }
+
+        if (newTab == null) {
+            return false;
+        }
+
+        // Move the newTab to the end of the queue
+        int index = mTabQueue.indexOf(newTab);
+        if (index != -1) {
+            mTabQueue.remove(index);
+        }
+        mTabQueue.add(newTab);
+
+        WebView mainView;
+        WebView subView;
+
+        // Display the new current tab
+        mCurrentTab = mTabs.indexOf(newTab);
+        mainView = newTab.mMainView;
+        boolean needRestore = (mainView == null);
+        if (needRestore) {
+            // Same work as in createNewTab() except don't do new Tab()
+            newTab.mMainView = mainView = new WebView(mActivity);
+            mainView.setMapTrackballToArrowKeys(false); // use t-ball directly
+
+            // Add this WebView to the settings observer list and update the
+            // settings
+            final BrowserSettings s = BrowserSettings.getInstance();
+            s.addObserver(mainView.getSettings()).update(s, null);
+        }
+        mainView.setWebViewClient(mActivity.getWebViewClient());
+        mainView.setWebChromeClient(mActivity.getWebChromeClient());
+        mainView.setOnCreateContextMenuListener(mActivity);
+        mainView.setDownloadListener(mActivity);
+        // Add the subwindow if it exists
+        if (newTab.mSubViewContainer != null) {
+            subView = newTab.mSubView;
+            subView.setWebViewClient(newTab.mSubViewClient);
+            subView.setWebChromeClient(newTab.mSubViewChromeClient);
+            subView.setOnCreateContextMenuListener(mActivity);
+            subView.setDownloadListener(mActivity);
+        }
+        if (needRestore) {
+            // Have to finish setCurrentTab work before calling restoreState
+            if (!restoreState(newTab.mSavedState, newTab)) {
+                mainView.loadUrl(BrowserSettings.getInstance().getHomePage());
+            }
+        }
+        return true;
+    }
+
+    /*
+     * Put the tab in the background using all the empty/background clients.
+     */
+    private void putTabInBackground(Tab t) {
+        WebView mainView = t.mMainView;
+        // Set an empty callback so that default actions are not triggered.
+        mainView.setWebViewClient(mEmptyClient);
+        mainView.setWebChromeClient(mBackgroundChromeClient);
+        mainView.setOnCreateContextMenuListener(null);
+        // Leave the DownloadManager attached so that downloads can start in
+        // a non-active window. This can happen when going to a site that does
+        // a redirect after a period of time. The user could have switched to
+        // another tab while waiting for the download to start.
+        mainView.setDownloadListener(mActivity);
+        WebView subView = t.mSubView;
+        if (subView != null) {
+            // Set an empty callback so that default actions are not triggered.
+            subView.setWebViewClient(mEmptyClient);
+            subView.setWebChromeClient(mBackgroundChromeClient);
+            subView.setOnCreateContextMenuListener(null);
+            subView.setDownloadListener(mActivity);
+        }
+    }
+
+    /*
+     * Dismiss the subwindow for the given tab.
+     */
+    void dismissSubWindow(Tab t) {
+        if (t != null && t.mSubView != null) {
+            BrowserSettings.getInstance().deleteObserver(
+                    t.mSubView.getSettings());
+            t.mSubView.destroy();
+            t.mSubView = null;
+            t.mSubViewContainer = null;
+        }
+    }
+
+    /**
+     * Ensure that Tab t has a title, url, and favicon.
+     * @param  t   Tab to populate.
+     */
+    /* package */ void populatePickerData(Tab t) {
+        if (t == null || t.mMainView == null) {
+            return;
+        }
+        // FIXME: The only place we cared about subwindow was for 
+        // bookmarking (i.e. not when saving state). Was this deliberate?
+        final WebBackForwardList list = t.mMainView.copyBackForwardList();
+        final WebHistoryItem item =
+                list != null ? list.getCurrentItem() : null;
+        populatePickerData(t, item);
+    }
+
+    // Populate the picker data
+    private void populatePickerData(Tab t, WebHistoryItem item) {
+        if (item != null) {
+            t.mUrl = item.getUrl();
+            t.mTitle = item.getTitle();
+            if (t.mTitle == null) {
+                t.mTitle = t.mUrl;
+            }
+        }
+    }
+    
+    /**
+     * Clean up the data for all tabs.
+     */
+    /* package */ void wipeAllPickerData() {
+        int size = getTabCount();
+        for (int i = 0; i < size; i++) {
+            final Tab t = getTab(i);
+            if (t != null && t.mSavedState == null) {
+                t.mUrl = null;
+                t.mTitle = null;
+            }
+        }
+    }
+
+    /*
+     * Save the state for an individual tab.
+     */
+    private boolean saveState(Tab t) {
+        if (t != null) {
+            final WebView w = t.mMainView;
+            // If the WebView is null it means we ran low on memory and we
+            // already stored the saved state in mSavedState.
+            if (w == null) {
+                return true;
+            }
+            final Bundle b = new Bundle();
+            final WebBackForwardList list = w.saveState(b);
+            if (list != null) {
+                final File f = new File(mThumbnailDir, w.hashCode()
+                        + "_pic.save");
+                if (w.savePicture(b, f)) {
+                    b.putString("picture", f.getPath());
+                }
+            }
+
+            // Store some extra info for displaying the tab in the picker.
+            final WebHistoryItem item =
+                    list != null ? list.getCurrentItem() : null;
+            populatePickerData(t, item);
+            if (t.mUrl != null) {
+                b.putString(CURRURL, t.mUrl);
+            }
+            if (t.mTitle != null) {
+                b.putString(CURRTITLE, t.mTitle);
+            }
+            b.putBoolean(CLOSEONEXIT, t.mCloseOnExit);
+
+            // Remember the parent tab so the relationship can be restored.
+            if (t.mParentTab != null) {
+                b.putInt(PARENTTAB, getTabIndex(t.mParentTab));
+            }
+
+            // Remember the saved state.
+            t.mSavedState = b;
+            return true;
+        }
+        return false;
+    }
+
+    /*
+     * Restore the state of the tab.
+     */
+    private boolean restoreState(Bundle b, Tab t) {
+        if (b == null) {
+            return false;
+        }
+        final WebView w = t.mMainView;
+        final WebBackForwardList list = w.restoreState(b);
+        if (list == null) {
+            return false;
+        }
+        if (b.containsKey("picture")) {
+            final File f = new File(b.getString("picture"));
+            w.restorePicture(b, f);
+            f.delete();
+        }
+        t.mSavedState = null;
+        t.mUrl = null;
+        t.mTitle = null;
+        t.mCloseOnExit = b.getBoolean(CLOSEONEXIT);
+        return true;
+    }
+}
