diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
new file mode 100644
index 0000000..3fe38e8
--- /dev/null
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -0,0 +1,195 @@
+/*
+ * 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" };
+    private static final String     WHERE_CLAUSE = "url = ? AND bookmark = 0";
+    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 = mAddress.getText().toString();
+        boolean emptyTitle = title.length() == 0;
+        boolean emptyUrl = unfilteredUrl.trim().length() == 0;
+        Resources r = getResources();
+        if (emptyTitle) {
+            if (emptyUrl) {
+                setTitle(r.getText(R.string.empty_bookmark));
+                return false;
+            }    
+            setTitle(r.getText(R.string.bookmark_needs_title));
+            return false;
+        }
+        if (emptyUrl) {
+            setTitle(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) {
+                setTitle(r.getText(R.string.bookmark_url_not_valid));
+                return false;
+            }
+            if (address.mHost.length() == 0) {
+                setTitle(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);
+                if (c.moveToFirst()) {
+                    // This means we have been to this site, so convert the 
+                    // history item to a bookmark.
+                    ContentValues map = new ContentValues();
+                    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 {
+                    // Adding a bookmark for a site the user has not been to.
+                    ContentValues map = new ContentValues();
+                    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);
+                    map.put(Browser.BookmarkColumns.VISITS, 0);
+                    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..748c9c2
--- /dev/null
+++ b/src/com/android/browser/AddNewBookmark.java
@@ -0,0 +1,72 @@
+/*
+ * 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) {
+        if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
+            mUrlText.setText(url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN));
+        } else {
+            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..0015eaf
--- /dev/null
+++ b/src/com/android/browser/BookmarkItem.java
@@ -0,0 +1,105 @@
+/*
+ * 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.widget.ImageView;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+/**
+ *  Custom layout for an item representing a bookmark in the browser.
+ */
+class BookmarkItem extends RelativeLayout {
+
+    private TextView    mTextView;
+    private TextView    mUrlText;
+    private ImageView   mImageView;
+    private LayoutInflater mFactory;
+
+    /**
+     *  Instantiate a bookmark item, including a default favicon.
+     *
+     *  @param context  The application context for the item.
+     */
+    BookmarkItem(Context context) {
+        super(context);
+
+        mFactory = LayoutInflater.from(context);
+        mFactory.inflate(R.layout.bookmark_item, 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(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 */ CharSequence getName() {
+        return mTextView.getText();
+    }
+
+    /**
+     * Return the TextView which holds the name of this bookmark item.
+     */
+    /* package */ TextView getNameTextView() {
+        return mTextView;
+    }
+
+    /**
+     *  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);
+    }
+}
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..fc4acfc
--- /dev/null
+++ b/src/com/android/browser/BrowserActivity.java
@@ -0,0 +1,4532 @@
+/*
+ * 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.ActivityManager;
+import android.app.AlertDialog;
+import android.app.SearchManager;
+import android.app.ProgressDialog;
+import android.content.ActivityNotFoundException;
+import android.content.res.AssetManager;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.ContentResolver;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.DialogInterface.OnCancelListener;
+import android.content.DialogInterface;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.ServiceConnection;
+import android.content.pm.ActivityInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+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.NetworkInfo;
+import android.net.Uri;
+import android.net.WebAddress;
+import android.net.http.EventHandler;
+import android.net.http.RequestQueue;
+import android.net.http.SslCertificate;
+import android.net.http.SslError;
+import android.os.Build;
+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.pim.DateFormat;
+import android.provider.Browser;
+import android.provider.Checkin;
+import android.provider.Contacts.Intents.Insert;
+import android.provider.Contacts;
+import android.provider.Downloads;
+import android.text.IClipboard;
+import android.text.util.Regex;
+import android.util.Config;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.view.MenuItem.OnMenuItemClickListener;
+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.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.animation.AlphaAnimation;
+import android.view.animation.Animation;
+import android.view.animation.AnimationSet;
+import android.view.animation.AnimationUtils;
+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.JsPromptResult;
+import android.webkit.JsResult;
+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 com.google.android.googleapps.IGoogleLoginService;
+import com.google.android.googlelogin.GoogleLoginServiceConstants;
+
+import java.io.BufferedOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.InputStream;
+import java.io.IOException;
+import java.net.MalformedURLException;
+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.HashSet;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import java.util.Vector;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+import java.util.zip.ZipInputStream;
+
+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() {
+                // 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;
+                    }
+                } 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;
+                    new Thread(getAccount).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() {
+            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 (mWebView != null)
+                    mWebView.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();
+            new Thread(copyPluginsFromAssets).start();
+          }
+        }
+    }
+
+
+    @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();
+
+        //
+        // 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 = new FrameLayout(this);
+
+        setContentView(mContentView);
+
+        // 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)) {
+            final Intent intent = getIntent();
+            final Bundle extra = intent.getExtras();
+            // Create an initial tab.
+            final TabControl.Tab t = mTabControl.createNewTab();
+            mTabControl.setCurrentTab(t);
+            // This is one of the only places we call attachTabToContentView
+            // without animating from the tab picker.
+            attachTabToContentView(t);
+            mWebView = t.getWebView();
+            if (extra != null) {
+                int scale = extra.getInt(Browser.INITIAL_ZOOM_LEVEL, 0);
+                if (scale > 0 && scale <= 1000) {
+                    mWebView.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()) {
+                    mWebView.loadUrl(mSettings.getHomePage());
+                } else {
+                    waitForCredentials();
+                }
+            } else {
+                mWebView.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());
+            mWebView = mTabControl.getCurrentWebView();
+        }
+
+        /* enables registration for changes in network status from
+           http stack */
+        mNetworkStateChangedFilter = new IntentFilter();
+        mNetworkStateChangedFilter.addAction(
+                RequestQueue.HTTP_NETWORK_STATE_CHANGED_INTENT);
+        mNetworkStateIntentReceiver = new BroadcastReceiver() {
+                @Override
+                public void onReceive(Context context, Intent intent) {
+                    if (intent.getAction().equals(
+                            RequestQueue.HTTP_NETWORK_STATE_CHANGED_INTENT)) {
+                        Boolean up = (Boolean)intent.getExtra(
+                                RequestQueue.HTTP_NETWORK_STATE_UP);
+                        onNetworkToggle(up);
+                    }
+                }
+            };
+        setRequestedOrientation(mSettings.getOrientation());
+    }
+
+    @Override
+    protected void onNewIntent(Intent intent) {
+        if (mWebView == null) {
+            return;
+        }
+        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)
+                || 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 and the
+                // url will be opened in the current tab
+                openTabAndShow(url, null);
+            } else {
+                if ("about:debug".equals(url)) {
+                    mSettings.toggleDebugSettings();
+                    return;
+                }
+                final TabControl.Tab currentTab = mTabControl.getCurrentTab();
+                // 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(currentTab, false, url,
+                            TAB_OVERVIEW_DELAY, null);
+                } else {
+                    // Get rid of the subwindow if it exists
+                    dismissSubWindow(currentTab);
+                    mWebView.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)
+                    || Intent.ACTION_WEB_SEARCH.equals(action)) {
+                url = intent.getStringExtra(SearchManager.QUERY);
+                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);
+            }
+        }
+        return url;
+    }
+
+    private 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 = mWebView;
+
+                    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 (!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);
+        }
+    }
+
+    @Override public void onLowMemory() {
+        super.onLowMemory();
+        mTabControl.freeMemory();
+    }
+
+    private boolean resumeWebView() {
+        if ((!mActivityInPause && !mPageStarted) || 
+                (mActivityInPause && mPageStarted)) {
+            CookieSyncManager.getInstance().startSync();
+            mWebView.resumeTimers();
+            return true;
+        } else {
+            return false;
+        }
+    }
+
+    private boolean pauseWebView() {
+        if (mActivityInPause && !mPageStarted) {
+            CookieSyncManager.getInstance().stopSync();
+            mWebView.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
+        mWebView.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();
+        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:
+                Message msg = mHandler.obtainMessage(
+                        FOCUS_NODE_HREF, id, 0);
+                WebView webview = getTopWindow();
+                msg.obj = webview;
+                webview.requestFocusNodeHref(msg);
+                break;
+
+            case R.id.download_context_menu_id:
+            case R.id.view_image_context_menu_id:
+                Message m = mHandler.obtainMessage(
+                        FOCUS_NODE_HREF, id, 0);
+                WebView w = getTopWindow();
+                m.obj = w;
+                w.requestImageRef(m);
+                break;
+            default:
+                // For other context menus
+                return onOptionsItemSelected(item);
+        }
+        mCanChord = false;
+        return true;
+    }
+    
+    /**
+     * 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, null, true); 
+        return true;
+    }
+
+    @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();
+                // TODO: Activities are requested to call onSearchRequested, and to override
+                // that function in order to insert custom fields (e.g. the search query).
+                startSearch(mSettings.getHomePage().equals(url) ? null : url, true, null, false);
+                }
+                break;
+                
+            case R.id.search_menu_id:
+                // launch using "global" search, which will bring up the Google search box
+                onSearchRequested(); 
+                break;
+        
+            case R.id.bookmarks_menu_id:
+                bookmarksPicker();
+                break;
+
+            case R.id.windows_menu_id:
+                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--;
+                    }
+                }
+                removeTabAndShow(currentIndex, indexToShow);
+                break;
+
+            case R.id.homepage_menu_id:
+                dismissSubWindow(mTabControl.getCurrentTab());
+                mWebView.loadUrl(mSettings.getHomePage());
+                break;
+
+            case R.id.preferences_menu_id:
+                Intent intent = new Intent(this,
+                        BrowserPreferencesPage.class);
+                startActivityForResult(intent, PREFERENCES_PAGE);
+                break;
+
+/*
+            Disable Find for version 1.0
+            case R.id.find_menu_id:
+                if (null == mFindDialog) {
+                    mFindDialog = new FindDialog(this);
+                    FrameLayout.LayoutParams lp = 
+                        new FrameLayout.LayoutParams(
+                        ViewGroup.LayoutParams.FILL_PARENT, 
+                        ViewGroup.LayoutParams.WRAP_CONTENT, 
+                        Gravity.BOTTOM);
+                        mFindDialog.setLayoutParams(lp);
+                }
+                mFindDialog.setWebView(getTopWindow());
+                mContentView.addView(mFindDialog);
+                mFindDialog.show();
+                Animation anim =AnimationUtils.loadAnimation(this,
+                        R.anim.find_dialog_enter);
+                mFindDialog.startAnimation(anim);
+                mMenuState = EMPTY_MENU;
+                break;
+*/
+
+            case R.id.page_info_menu_id:
+                showPageInfo(mWebView, false);
+                break;
+
+            case R.id.classic_history_menu_id: {
+                    Intent i = new Intent(this, BrowserHistoryPage.class);
+                    i.putExtra("maxTabsOpen",
+                            mTabControl.getTabCount() >=
+                            TabControl.MAX_TABS);
+                    startActivityForResult(i, CLASSIC_HISTORY_PAGE);
+                }
+                break;
+
+            case R.id.bookmark_page_menu_id:
+                Browser.saveBookmark(this, getTopWindow().getTitle(),
+                        getTopWindow().getUrl());
+                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_menu_id:
+                // FIXME: Can we move this out of WebView? How does this work
+                // for a subwindow?
+                getTopWindow().invokeZoomPicker();
+                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;
+                
+            case R.id.flip_orientation_menu_id:
+                if (mSettings.getOrientation() != 
+                        ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
+                mSettings.setOrientation(this, 
+                        ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
+                } else {
+                    mSettings.setOrientation(this,
+                            ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED);
+                }
+                setRequestedOrientation(mSettings.getOrientation());
+                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: {
+                    Intent i = new Intent(this, BrowserHistoryPage.class);
+                    i.putExtra("maxTabsOpen",
+                            mTabControl.getTabCount() >=
+                            TabControl.MAX_TABS);
+                    startActivityForResult(i, CLASSIC_HISTORY_PAGE);
+                }
+                break;
+
+            case R.id.bookmarks_tab_menu_id:
+                bookmarksPicker();
+                break;
+
+            case R.id.properties_tab_menu_id:
+                if (mTabListener != null && mTabOverview != null) {
+                    int pos = mTabOverview.getContextMenuPosition(item);
+                    TabControl.Tab t = mTabControl.getTab(pos);
+                    // Use the tab's data for the page info dialog.
+                    if (t.getWebView() != null) {
+                        showPageInfo(t.getWebView(), false);
+                    }
+                    // FIXME: what should we display if the WebView is null?
+                }
+                break;
+
+            default:
+                if (!super.onOptionsItemSelected(item)) {
+                    return false;
+                }
+                // Otherwise fall through.
+        }
+        mCanChord = false;
+        return true;
+    }
+
+    public void closeFind() {
+        Animation anim = AnimationUtils.loadAnimation(this,
+                R.anim.find_dialog_exit);
+        mFindDialog.startAnimation(anim);
+        mContentView.removeView(mFindDialog);
+        getTopWindow().requestFocus();
+        mMenuState = R.id.MAIN_MENU;
+    }
+
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent event) {
+        if (super.dispatchTouchEvent(event)) {
+            return true;
+        } else {
+            // We do not use the Dialog class because it places dialogs in the
+            // middle of the screen.  It would take care of dismissing find if
+            // were using it, but we are doing it manually since we are not.
+            if (mFindDialog != null && mFindDialog.hasFocus()) {
+                mFindDialog.dismiss();
+            }
+            return false;
+        }
+    }
+    
+    @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.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.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.setGroupVisible(R.id.TAB_MENU, false);
+                    menu.setGroupEnabled(R.id.TAB_MENU, false);
+                }
+                final WebView w = getTopWindow();
+                boolean canGoBack = w.canGoBack();
+                final MenuItem back = menu.findItem(R.id.back_menu_id);
+                back.setVisible(canGoBack);
+                back.setEnabled(canGoBack);
+                final MenuItem close = menu.findItem(R.id.close_menu_id);
+                close.setVisible(!canGoBack);
+                close.setEnabled(!canGoBack);
+                final MenuItem flip = 
+                        menu.findItem(R.id.flip_orientation_menu_id);
+                boolean keyboardClosed = 
+                        getResources().getConfiguration().keyboardHidden == 
+                        Configuration.KEYBOARDHIDDEN_YES;
+                flip.setEnabled(keyboardClosed);
+
+                boolean isHome = mSettings.getHomePage().equals(w.getUrl());
+                final MenuItem home = menu.findItem(R.id.homepage_menu_id);
+                home.setVisible(!isHome);
+                home.setEnabled(!isHome);
+
+                menu.findItem(R.id.forward_menu_id)
+                        .setEnabled(w.canGoForward());
+
+                menu.findItem(R.id.zoom_in_menu_id).setVisible(false);
+                menu.findItem(R.id.zoom_out_menu_id).setVisible(false);
+                
+                // decide whether to show the share link option
+                PackageManager pm = getPackageManager();
+                Intent send = new Intent(Intent.ACTION_SEND);
+                send.setType("text/plain");
+                List<ResolveInfo> list = pm.queryIntentActivities(send,
+                        PackageManager.MATCH_DEFAULT_ONLY);
+                menu.findItem(R.id.share_page_menu_id).setVisible(
+                        list.size() > 0);
+
+                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.IMAGE_ANCHOR_TYPE
+                || type == WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE);
+        menu.setGroupVisible(R.id.ANCHOR_MENU,
+                type == WebView.HitTestResult.ANCHOR_TYPE ||
+                type == WebView.HitTestResult.IMAGE_ANCHOR_TYPE
+                || 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(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,
+                        Contacts.People.CONTENT_URI);
+                addIntent.putExtra(Insert.FULL_MODE, true);
+                addIntent.putExtra(Insert.PHONE, extra);
+                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.ANCHOR_TYPE:
+            case WebView.HitTestResult.IMAGE_ANCHOR_TYPE:
+            case WebView.HitTestResult.SRC_ANCHOR_TYPE:
+            case WebView.HitTestResult.SRC_IMAGE_ANCHOR_TYPE:
+                mTitleView = (TextView) LayoutInflater.from(this)
+                        .inflate(android.R.layout.browser_link_context_header,
+                        null);
+                menu.setHeaderView(mTitleView);
+                // 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);
+                if (type == WebView.HitTestResult.ANCHOR_TYPE
+                        || type == WebView.HitTestResult.IMAGE_ANCHOR_TYPE){
+                    menu.findItem(R.id.bookmark_context_menu_id).setVisible(
+                            false);
+                    menu.findItem(R.id.save_link_context_menu_id).setVisible(
+                            false);
+                    menu.findItem(R.id.copy_link_context_menu_id).setVisible(
+                            false);
+                    menu.findItem(R.id.share_link_context_menu_id).setVisible(
+                            false);
+                    mTitleView.setText(R.string.contextmenu_javascript);
+                    break;
+                }
+                Message headerMessage = mHandler.obtainMessage(FOCUS_NODE_HREF,
+                        HEADER_FLAG, 0);
+                headerMessage.obj = webview;
+                webview.requestFocusNodeHref(headerMessage);
+                // decide whether to show the share link option
+                PackageManager pm = getPackageManager();
+                Intent send = new Intent(Intent.ACTION_SEND);
+                send.setType("text/plain");
+                List<ResolveInfo> list = pm.queryIntentActivities(send,
+                        PackageManager.MATCH_DEFAULT_ONLY);
+                menu.findItem(R.id.share_link_context_menu_id).setVisible(
+                        list.size() > 0);
+                if (type == WebView.HitTestResult.ANCHOR_TYPE) {
+                    break;
+                }
+                //fall through
+
+            case WebView.HitTestResult.IMAGE_TYPE:
+                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);
+        // Reset the current WebView.
+        mWebView = tab.getWebView();
+        // Set the view to invisibile for now.
+        mWebView.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);
+        map.put("url", 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.
+        if (mTabOverview != null) {
+            mTabOverview.setListener(null);
+        }
+        mTabListener = null;
+
+    }
+
+    // 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) {
+        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);
+                    mWebView.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(),
+                        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.
+                mWebView.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) {
+        if (mTabOverview == null) {
+            return;
+        }
+
+        // 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) {
+                        if (mTabOverview != null) {
+                            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 String url, final Message msg) {
+        // mTabOverview may have been dismissed
+        if (mTabOverview == null) {
+            return;
+        }
+
+        // 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);
+
+        // Use a delay of 1 second in case we get a bad position
+        long delay = 1000;
+        boolean fade = false;
+
+        // Wait until the animation completes to load the url.
+        final Animation.AnimationListener l =
+                new Animation.AnimationListener() {
+                    public void onAnimationStart(Animation a) {}
+                    public void onAnimationRepeat(Animation a) {}
+                    public void onAnimationEnd(Animation a) {
+                        // The animation is done so allow key events and other
+                        // animations to begin.
+                        mAnimationCount--;
+                        mHandler.post(new Runnable() {
+                            public void run() {
+                                if (v != null) {
+                                    mContentView.removeView(view);
+                                    mWebView.setVisibility(View.VISIBLE);
+                                    // Make the sub window container visible if
+                                    // there is one.
+                                    if (mTabControl.getCurrentSubWindow() != null) {
+                                        mTabControl.getCurrentTab()
+                                                .getSubWebViewContainer()
+                                                .setVisibility(View.VISIBLE);
+                                    }
+                                }
+                                if (url != null) {
+                                    // Dismiss the subwindow if one exists.
+                                    dismissSubWindow(
+                                            mTabControl.getCurrentTab());
+                                    mWebView.loadUrl(url);
+                                }
+                                mMenuState = R.id.MAIN_MENU;
+                                // Resume regular updates.
+                                mWebView.resumeTimers();
+                                // Dispatch the message after the animation
+                                // completes.
+                                if (msg != null) {
+                                    msg.sendToTarget();
+                                }
+                            }
+                        });
+                    }
+                };
+
+        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);
+            // Dismiss the tab overview after the animation completes.
+            delay = anim.getDuration();
+        } else {
+            // dismiss mTabOverview and have it fade out just in case we get a
+            // bad location.
+            fade = true;
+            // Go ahead and load the url.
+            l.onAnimationEnd(null);
+        }
+        // Reset all the title bar info.
+        resetTitle();
+        // Dismiss the tab overview either after the animation or after a
+        // second.
+        mHandler.sendMessageDelayed(mHandler.obtainMessage(
+                DISMISS_TAB_OVERVIEW, fade ? 1 : 0, 0), delay);
+    }
+
+    private void openTab(String url) {
+        if (mSettings.openInBackground()) {
+            TabControl.Tab t = mTabControl.createNewTab();
+            if (t != null) {
+                WebView w = t.getWebView();
+                w.loadUrl(url);
+            }
+        } else {
+            openTabAndShow(url, null);
+        }
+    }
+
+    private class Copy implements OnMenuItemClickListener {
+        private CharSequence mText;
+
+        public boolean onMenuItemClick(MenuItem item) {
+            copy(mText);
+            return true;
+        }
+
+        public Copy(CharSequence toCopy) {
+            mText = toCopy;
+        }
+    }
+
+    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() {
+        resetTitleAndIcon(mWebView);
+        int progress = mWebView.getProgress();
+        mInLoad = (progress != 100);
+        updateInLoadMenuItems();
+        mWebChromeClient.onProgressChanged(mWebView, 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;
+
+        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) {
+        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 removeTabAndShow(int indexToRemove, int indexToShow) {
+        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, indexToRemove, true);
+        // Change to the parent tab
+        final TabControl.Tab tab = mTabControl.getTab(indexToShow);
+        if (tab != null) {
+            sendAnimateFromOverview(tab, false, null, delay, null);
+        } else {
+            // Send a message to open a new tab.
+            mHandler.sendMessageDelayed(
+                    mHandler.obtainMessage(OPEN_TAB_AND_SHOW,
+                        mSettings.getHomePage()), delay);
+        }
+    }
+
+    private void goBackOnePageOrQuit() {
+        if (mWebView.canGoBack()) {
+            mWebView.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 = mTabControl.getCurrentTab().getParentTab();
+            if (parent != null) {
+                removeTabAndShow(mTabControl.getCurrentIndex(),
+                        mTabControl.getTabIndex(parent));
+            } else {
+                /*
+                 * 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.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 (mMenuState == R.id.MAIN_MENU){
+                        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 JS_CONFIRM              = 101;
+    private static final int FOCUS_NODE_HREF         = 102;
+    private static final int DISMISS_TAB_OVERVIEW    = 103;
+    private static final int CANCEL_CREDS_REQUEST    = 104;
+    private static final int ANIMATE_FROM_OVERVIEW   = 105;
+    private static final int ANIMATE_TO_OVERVIEW     = 106;
+    private static final int OPEN_TAB_AND_SHOW       = 107;
+    private static final int CHECK_MEMORY            = 108;
+    private static final int RELEASE_WAKELOCK        = 109;
+
+    // Private handler for handling javascript and saving passwords
+    private Handler mHandler = new Handler() {
+
+        public void handleMessage(Message msg) {
+            switch (msg.what) {
+                case JS_CONFIRM:
+                    JsResult res = (JsResult) msg.obj;
+                    if (msg.arg1 == 0) {
+                        res.cancel();
+                    } else {
+                        res.confirm();
+                    }
+                    break;
+
+                case DISMISS_TAB_OVERVIEW:
+                    if (mTabOverview != null) {
+                        if (msg.arg1 == 1) {
+                            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
+                        mWebView.setVisibility(View.VISIBLE);
+                        // Make the sub window container visible.
+                        if (mTabControl.getCurrentSubWindow() != null) {
+                            mTabControl.getCurrentTab().getSubWebViewContainer()
+                                    .setVisibility(View.VISIBLE);
+                        }
+                        mContentView.removeView(mTabOverview);
+                        mTabOverview.clear();
+                        // XXX: There are checks for mTabOverview throughout
+                        // this file because this message can be received
+                        // before it is expected. This is because we are not
+                        // enforcing the order of animations properly. In order
+                        // to get this right, we would need to rewrite a lot of
+                        // the code to dispatch this messages after all
+                        // animations have completed.
+                        mTabOverview = null;
+                        mTabListener = null;
+                    }
+                    break;
+                    
+                case ANIMATE_FROM_OVERVIEW:
+                    final HashMap map = (HashMap) msg.obj;
+                    animateFromTabOverview((AnimatingView) map.get("view"),
+                            msg.arg1 == 1, (String) map.get("url"),
+                            (Message) map.get("msg"));
+                    break;
+
+                case ANIMATE_TO_OVERVIEW:
+                    animateToTabOverview(msg.arg1, msg.arg2 == 1,
+                            (AnimatingView) msg.obj);
+                    break;
+
+                case OPEN_TAB_AND_SHOW:
+                    openTabAndShow((String) msg.obj, null);
+                    break;
+
+                case FOCUS_NODE_HREF:
+                    String url = (String) msg.getData().get("url");
+                    if (url == null || url.length() == 0) {
+                        break;
+                    }
+                    WebView view = (WebView) msg.obj;
+                    // Only apply the action if the top window did not change.
+                    if (getTopWindow() != view) {
+                        break;
+                    }
+                    switch (msg.arg1) {
+                        case HEADER_FLAG:
+                            mTitleView.setText(url);
+                            break;
+                        case R.id.open_context_menu_id:
+                        case R.id.view_image_context_menu_id:
+                            loadURL(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((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;
+            }
+        }
+    };
+
+    private static final int HEADER_FLAG = Integer.MIN_VALUE;
+    private TextView mTitleView = null;
+
+    // -------------------------------------------------------------------------
+    // 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 final WebViewClient mWebViewClient = new WebViewClient() {
+        @Override
+        public void onPageStarted(WebView view, String url, Bitmap favicon) {
+            resetLockIcon(url);
+            setUrlTitle(url, null);
+            // Call onReceivedIcon instead of setFavicon so the bookmark
+            // database can be updated.
+            mWebChromeClient.onReceivedIcon(view, 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();
+
+            // 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);
+            // Make the progress full.
+            getWindow().setFeatureInt(Window.FEATURE_PROGRESS, 10000);
+
+            // 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.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(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) {
+                String[] credentials =
+                    mWebView.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 (event.isDown()) {
+                mKeyTracker.doKeyDown(event.getKeyCode(), event);
+            } else {
+                mKeyTracker.doKeyUp(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);
+                parent.addChildTab(mTabControl.getCurrentTab());
+                WebView.WebViewTransport transport = 
+                    (WebView.WebViewTransport) msg.obj;
+                transport.setWebView(mWebView);
+            }
+        }
+
+        @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(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(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(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.
+                removeTabAndShow(currentIndex, mTabControl.getTabIndex(parent));
+            }
+        }
+
+        @Override
+        public void onProgressChanged(WebView view, int newProgress) {
+            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.getUrl();
+
+            // 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()) {
+                    Log.d(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) {
+            if (icon != null) {
+                BrowserBookmarksAdapter.updateBookmarkFavicon(mResolver,
+                        view.getUrl(), icon);
+            }
+            setFavicon(icon);
+        }
+
+        //----------------------------------------------------------------------
+        // JavaScript functions.
+        //----------------------------------------------------------------------
+
+        // Show an alert to the user.
+        @Override
+        public boolean onJsAlert(WebView view, String url, String message,
+                JsResult result) {
+            String title = url;
+            if (URLUtil.isDataUrl(url)) {
+                // For data: urls, we just display 'JavaScript' similar to
+                // Safari.
+                title = getString(R.string.js_dialog_title_default);
+            } else {
+                try {
+                    URL aUrl = new URL(url);
+                    // Example: "The page at 'http://www.mit.edu' says:"
+                    title = getText(R.string.js_dialog_title_prefix)
+                        + " '"
+                        + (aUrl.getProtocol() + "://" + aUrl.getHost())
+                        + "' "
+                        + getText(R.string.js_dialog_title_suffix);
+                } catch (MalformedURLException ex) {
+                    // do nothing. just use the url passed as the title
+                }
+            }
+            final JsResult res = result;
+            new AlertDialog.Builder(BrowserActivity.this)
+                    .setTitle(title)
+                    .setMessage(message)
+                    .setPositiveButton(R.string.ok,
+                            new AlertDialog.OnClickListener() {
+                                public void onClick(DialogInterface dialog,
+                                        int which) {
+                                    res.confirm();
+                                }
+                            })
+                    .setCancelable(false)
+                    .show();
+            return true;
+        }
+
+        @Override
+        public boolean onJsConfirm(WebView view, String url, String message,
+                final JsResult result) {
+            String title = url;
+            try {
+                URL aUrl = new URL(url);
+                // Example: "The page at 'http://www.mit.edu' says:"
+                title = getText(R.string.js_dialog_title_prefix)
+                    + " '"
+                    + (aUrl.getProtocol() + "://" + aUrl.getHost())
+                    + "' "
+                    + getText(R.string.js_dialog_title_suffix);
+            } catch (MalformedURLException ex) {
+                // do nothing. just use the url passed as the title
+            }
+            new AlertDialog.Builder(BrowserActivity.this)
+                .setTitle(title)
+                .setMessage(message)
+                .setPositiveButton(R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        mHandler.obtainMessage(JS_CONFIRM, 1, 0, result).sendToTarget();
+                    }})
+                .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        mHandler.obtainMessage(JS_CONFIRM, 0, 0, result).sendToTarget();
+                    }})
+                .show();
+            // Return true so WebView knows we will handle the confirm.
+            return true;
+        }
+
+        @Override
+        public boolean onJsPrompt(WebView view, String url, String message, String defaultValue,
+                final JsPromptResult result) {
+            String title = url;
+            try {
+                URL aUrl = new URL(url);
+                // Example: "The page at 'http://www.mit.edu' says:"
+                title = getText(R.string.js_dialog_title_prefix)
+                    + " '"
+                    + (aUrl.getProtocol() + "://" + aUrl.getHost())
+                    + "' "
+                    + getText(R.string.js_dialog_title_suffix);
+            } catch (MalformedURLException ex) {
+                // do nothing, just use the url passed as the title
+            }
+
+            final LayoutInflater factory = LayoutInflater.from(BrowserActivity.this);
+            final View v = factory.inflate(R.layout.js_prompt, null);
+            ((TextView)v.findViewById(R.id.message)).setText(message);
+            ((EditText)v.findViewById(R.id.value)).setText(defaultValue);
+
+            new AlertDialog.Builder(BrowserActivity.this)
+                .setTitle(title)
+                .setView(v)
+                .setPositiveButton(R.string.ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                String value = ((EditText)v.findViewById(R.id.value)).getText()
+                                        .toString();
+                                result.confirm(value);
+                            }
+                        })
+                .setNegativeButton(R.string.cancel,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int whichButton) {
+                                result.cancel();
+                            }
+                        })
+                .setOnCancelListener(
+                        new DialogInterface.OnCancelListener() {
+                            public void onCancel(DialogInterface dialog) {
+                                result.cancel();
+                            }
+                        })
+                .show();
+
+            // Return true so WebView knows we will handle the prompt.
+            return true;
+        }
+
+        @Override
+        public boolean onJsBeforeUnload(WebView view, String url,
+                String message, final JsResult result) {
+            final String m =
+                    getString(R.string.js_dialog_before_unload, message);
+            new AlertDialog.Builder(BrowserActivity.this)
+                    .setMessage(m)
+                    .setPositiveButton(R.string.ok,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog,
+                                        int which) {
+                                    // Use JS_CONFIRM since it has the same
+                                    // behavior we want here.
+                                    mHandler.obtainMessage(JS_CONFIRM, 1, 0,
+                                            result).sendToTarget();
+                                }})
+                    .setNegativeButton(R.string.cancel,
+                            new DialogInterface.OnClickListener() {
+                                public void onClick(DialogInterface dialog,
+                                        int which) {
+                                    // Use JS_CONFIRM since it has the same
+                                    // behavior we want here.
+                                    mHandler.obtainMessage(JS_CONFIRM, 0, 0,
+                                            result).sendToTarget();
+                                }})
+                    .show();
+            // Return true so WebView knows we will handle the dialog.
+            return true;
+        }
+    };
+
+    /**
+     * 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().queryIntentActivities(intent,
+                        PackageManager.MATCH_DEFAULT_ONLY).size() != 0) {
+                // 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
+     */
+    public 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
+        if (!Environment.getExternalStorageState().
+                equals(Environment.MEDIA_MOUNTED)) {
+            String msg =
+                getString(R.string.download_no_sdcard_dlg_msg, filename);
+
+            new AlertDialog.Builder(this)
+                .setTitle(R.string.download_no_sdcard_dlg_title)
+                .setIcon(R.drawable.ic_dialog_alert)
+                .setMessage(msg)
+                .setPositiveButton(R.string.ok, null)
+                .show();
+            return;
+        }
+
+        String cookies = CookieManager.getInstance().getCookie(url);
+
+        ContentValues values = new ContentValues();
+        values.put(Downloads.URI, url);
+        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.parse(url).getHost());
+        if (contentLength > 0) {
+            values.put(Downloads.TOTAL_BYTES, contentLength);
+        }
+        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;
+        }
+        getWindow().setFeatureDrawable(Window.FEATURE_RIGHT_ICON, d);
+    }
+
+    /**
+     * Displays a page-info dialog.
+     * @param view The target web-view.
+     * @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 WebView view,
+                              final boolean fromShowSSLCertificateOnError) {
+        final LayoutInflater factory = LayoutInflater
+                .from(this);
+
+        final View pageInfoView = factory.inflate(R.layout.page_info, null);
+
+        String url = null;
+        String title = null;
+
+        // Use the cached title and url if this is the current WebView
+        if (view == mWebView) {
+            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 = view;
+        mPageInfoFromShowSSLCertificateOnError = new Boolean(fromShowSSLCertificateOnError);
+
+        AlertDialog.Builder alertDialogBuilder =
+            new AlertDialog.Builder(this)
+            .setTitle(R.string.page_info).setIcon(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.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(view);
+                            }
+                        }
+                    }
+                });
+        }
+
+        mPageInfoDialog = alertDialogBuilder.show();
+    }
+
+       /**
+     * Displays the main top-level page SSL certificate dialog
+     * (accessible from the Page-Info dialog).
+     * @param view The target web-view.
+     */
+    private void showSSLCertificate(final WebView view) {
+        final View certificateView =
+            inflateCertificateView(mWebView.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 = view;
+        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(view, false);
+                            }
+                        })
+                .setOnCancelListener(
+                        new DialogInterface.OnCancelListener() {
+                            public void onCancel(DialogInterface dialog) {
+                                mSSLCertificateDialog = null;
+                                mSSLCertificateView = null;
+
+                                showPageInfo(view, 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(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;
+        mHttpAuthenticationDialog = new AlertDialog.Builder(this)
+                .setTitle(titleText)
+                .setIcon(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;
+                        }})
+                .show();
+        if (focusId != 0) {
+            mHttpAuthenticationDialog.findViewById(focusId).requestFocus();
+        } else {
+            v.findViewById(R.id.username_edit).requestFocus();
+        }
+    }
+
+    public int getProgress() {
+        return mWebView.getProgress();
+    }
+
+    /**
+     * 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) {
+        mWebView.setHttpAuthUsernamePassword(host, realm, username, password);
+    }
+
+    /**
+     * http stack 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) {
+            if (mAlertDialog != null) {
+                mAlertDialog.cancel();
+                mAlertDialog = null;
+            }
+        } else {
+            if (mInLoad && mAlertDialog == null) {
+                mAlertDialog = new AlertDialog.Builder(this)
+                        .setTitle(R.string.loadSuspendedTitle)
+                        .setMessage(R.string.loadSuspended)
+                        .setPositiveButton(R.string.ok, null)
+                        .show();
+            }
+        }
+    }
+
+    @Override
+    protected void onActivityResult(int requestCode, int resultCode,
+                                    Intent intent) {
+        switch (requestCode) {
+            case BOOKMARKS_PAGE:
+            case CLASSIC_HISTORY_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 {
+                        // 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(mTabControl.getCurrentTab(),
+                                    false, data, TAB_OVERVIEW_DELAY, null);
+                        } else {
+                            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.
+     */
+    private 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();
+            }
+
+            mTabControl.removeTab(mTabControl.getTab(position));
+            // 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(position);
+            } else {
+                position--;
+            }
+
+            // FIXME: This isn't really right. We don't have a current WebView
+            // since we are switching between tabs and haven't selected a new
+            // one. This just prevents a NPE in case the user hits home from the
+            // tab switcher.
+            int index = position;
+            if (index == ImageGrid.NEW_TAB) {
+                index = 0;
+            }
+            final TabControl.Tab t = mTabControl.getTab(index);
+            // Only the current tab ensures its WebView is non-null. This
+            // implies that we are reloading the freed tab.
+            mTabControl.setCurrentTab(t);
+            mWebView = t.getWebView();
+        }
+        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();
+            BrowserActivity.this.getWindow().setFeatureInt(
+                    Window.FEATURE_PROGRESS, Window.PROGRESS_VISIBILITY_ON);
+            BrowserActivity.this.mMenuState = EMPTY_MENU;
+
+            // NEW_TAB means that the "New Tab" cell was clicked on.
+            if (index == ImageGrid.NEW_TAB) {
+                openTabAndShow(mSettings.getHomePage(), null);
+            } 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);
+            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++;
+        if (stay) {
+            getWindow().setFeatureDrawable(Window.FEATURE_LEFT_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 bookmarksPicker() {
+        Intent intent = new Intent(this,
+                BrowserBookmarksPage.class);
+        String title = mWebView.getTitle();
+        String url = mWebView.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);
+        startActivityForResult(intent, BOOKMARKS_PAGE);
+    }
+
+    // Called when loading from bookmarks or goto.
+    private void loadURL(String url) {
+        // In case the user enters nothing.
+        if (url != null && url.length() != 0) {
+            url = smartUrlFilter(url);
+            WebView w = getTopWindow();
+            if (!mWebViewClient.shouldOverrideUrlLoading(w, url)) {
+                w.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 inUrl) {
+
+        boolean hasSpace = inUrl.indexOf(' ') != -1;
+
+        if (!hasSpace) {
+            Matcher matcher = ACCEPTED_URI_SCHEMA.matcher(inUrl);
+            if (matcher.matches()) {
+                // 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 */static String composeSearchUrl(String search) {
+        return URLUtil.composeSearchUrl(search, QuickSearch_G,
+                QUERY_PLACE_HOLDER);
+    }
+
+    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 WebView         mWebView;
+    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 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 WebView 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 WebView 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
+    final static String QuickSearch_G =
+            "http://www.google.com/m?client=ms-"
+            + SystemProperties.get("ro.com.google.clientid", "unknown")
+            + "&source=android-chrome&q=%s";
+    // 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";
+
+    private final static String QUERY_PLACE_HOLDER = "%s";
+
+    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;
+
+    // monitor platform changes
+    private IntentFilter mNetworkStateChangedFilter;
+    private BroadcastReceiver mNetworkStateIntentReceiver;
+
+    // activity requestCode
+    final static int BOOKMARKS_PAGE         = 1;
+    final static int CLASSIC_HISTORY_PAGE   = 2;
+    final static int DOWNLOAD_PAGE          = 3;
+    final static int PREFERENCES_PAGE       = 4;
+
+    // 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..3b76e75
--- /dev/null
+++ b/src/com/android/browser/BrowserBookmarksAdapter.java
@@ -0,0 +1,522 @@
+/*
+ * 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;
+        }
+        final String[] selArgs = new String[] { url };
+        final String where = Browser.BookmarkColumns.URL + " == ? 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..f938ff9
--- /dev/null
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -0,0 +1,356 @@
+/*
+ * 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.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;
+    
+    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.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("title"), 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 = new Intent();
+                intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(Intent.ACTION_VIEW,
+                        Uri.parse(getUrl(position))));
+                intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getBookmarkTitle(position));
+                intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
+                        Intent.ShortcutIconResource.fromContext(BrowserBookmarksPage.this,
+                                R.drawable.ic_launcher_browser));
+                setResult(RESULT_OK, intent);
+                finish();
+            }
+        }
+    };
+
+    private void saveCurrentPage() {
+        Intent i = new Intent(BrowserBookmarksPage.this,
+                AddBookmarkPage.class);
+        i.putExtras(getIntent());
+        startActivityForResult(i, BOOKMARKS_SAVE);
+    }
+
+    private void loadUrl(int position) {
+        setResult(RESULT_OK, (new Intent()).setAction(getUrl(position)));
+        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);
+        setResult(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(R.drawable.ssl_icon)
+                .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()) {
+            setResult(RESULT_CANCELED);
+            mCanceled = true;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+}
diff --git a/src/com/android/browser/BrowserDownloadAdapter.java b/src/com/android/browser/BrowserDownloadAdapter.java
new file mode 100644
index 0000000..b3e08f5
--- /dev/null
+++ b/src/com/android/browser/BrowserDownloadAdapter.java
@@ -0,0 +1,221 @@
+/*
+ * 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.Formatter;
+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.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.FILENAME);
+        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.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_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..e2b11a6
--- /dev/null
+++ b/src/com/android/browser/BrowserDownloadPage.java
@@ -0,0 +1,470 @@
+/*
+ * 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.FILENAME, 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;
+            
+            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) {
+        Uri record = ContentUris.withAppendedId(Downloads.CONTENT_URI, id);
+        ContentValues values = new ContentValues();
+        values.put(Downloads.CONTROL, Downloads.CONTROL_RUN);
+        getContentResolver().update(record, values, null, null);
+    }
+    
+    /**
+     * 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()) {
+            StringBuffer where = new StringBuffer();
+            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()) {
+            StringBuffer where = new StringBuffer();
+            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.FILENAME);
+        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..3059126
--- /dev/null
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -0,0 +1,377 @@
+/*
+ * 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.content.Intent;
+import android.content.pm.PackageManager;
+import android.content.pm.ResolveInfo;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.graphics.Bitmap;
+import android.os.Bundle;
+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.ListAdapter;
+import android.widget.ListView;
+import android.widget.TextView;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Vector;
+
+/**
+ * Activity for displaying the browser's history, divided into
+ * days of viewing.
+ */
+public class BrowserHistoryPage extends ListActivity {
+    private HistoryAdapter          mAdapter;
+    private DateSorter              mDateSorter;
+    private boolean                 mMaxTabsOpen;
+
+    private final static String LOGTAG = "browser";
+
+    // FIXME: Make this a part of Browser so we do not have more than one
+    // copy (other copy is in BrowserBookmarksAdapter).
+    // Used to store favicons as we get them from the database
+    private final HashMap<String, Bitmap> mUrlsToIcons =
+            new HashMap<String, Bitmap>();
+    // Implementation of WebIconDatabase.IconListener
+    private class IconReceiver implements IconListener {
+        public void onReceivedIcon(String url, Bitmap icon) {
+            mUrlsToIcons.put(url, 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);
+        }
+        setResult(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);
+        ListView list = getListView();
+        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);
+
+        mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
+        Browser.requestAllIcons(getContentResolver(), null, mIconReceiver);
+        
+        // initialize the result to canceled, so that if the user just presses
+        // back then it will have the correct result
+        setResult(RESULT_CANCELED);
+    }
+
+    @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) {
+        AdapterView.AdapterContextMenuInfo i = 
+            (AdapterView.AdapterContextMenuInfo)
+            menuInfo;
+
+        // 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");
+        List<ResolveInfo> list = pm.queryIntentActivities(send,
+                PackageManager.MATCH_DEFAULT_ONLY);
+        menu.findItem(R.id.share_link_context_menu_id).setVisible(
+                list.size() > 0);
+        
+        super.onCreateContextMenu(menu, v, menuInfo);
+    }
+    
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo i = 
+            (AdapterView.AdapterContextMenuInfo)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
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        if (v instanceof HistoryItem) {
+            loadUrl(((HistoryItem) v).getUrl(), false);
+        }
+    }
+
+    private class HistoryAdapter implements ListAdapter {
+        
+        // Map of items. Negative values are labels, positive values
+        // and zero are cursor offsets.
+        int mItemMap[];
+        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();
+        }
+        
+        void refreshData() {
+            mCursor.requery();
+            buildMap();
+            for (DataSetObserver o : mObservers) {
+                o.onChanged();
+            }
+        }
+        
+        public void buildMap() {
+            // The cursor is sorted by date
+            // Make one pass to build up the ItemMap with the inserted 
+            // section separators. 
+            int array[] = new int[mCursor.getCount() + DateSorter.DAY_COUNT];
+            int dateIndex = -1;
+            if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
+                int itemIndex = 0;
+                while (!mCursor.isAfterLast()) {
+                    long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
+                    int index = mDateSorter.getIndex(date);
+                    if (index > dateIndex) {
+                        dateIndex = index;
+                        array[itemIndex] = dateIndex - DateSorter.DAY_COUNT;
+                        itemIndex++;
+                    }
+                    array[itemIndex] = mCursor.getPosition();
+                    itemIndex++;
+                    mCursor.moveToNext();
+                }
+            } else {
+                // The db is empty, just add the heading for the first item
+                dateIndex = 0;
+                array[0] = dateIndex - DateSorter.DAY_COUNT;
+            }
+            // Compress the array as the trailing date sections may be
+            // empty
+            int extraEntries = DateSorter.DAY_COUNT - dateIndex - 1;
+            if (extraEntries > 0) {
+                int newArraySize = array.length - extraEntries;
+                mItemMap = new int[newArraySize];
+                System.arraycopy(array, 0, mItemMap, 0, newArraySize);
+            } else {
+                mItemMap = array;
+            }
+        }
+
+        public View getView(int position, View convertView, ViewGroup parent) {
+            if (mItemMap[position] < 0) {
+                return getHeaderView(position, convertView);
+            }
+            return getHistoryItem(position, convertView);
+        }
+        
+        View getHistoryItem(int position, View convertView) {
+            HistoryItem item;
+            if (null == convertView || !(convertView instanceof HistoryItem)) {
+                item = new HistoryItem(BrowserHistoryPage.this);
+            } else {
+                item = (HistoryItem) convertView;
+            }
+            mCursor.moveToPosition(mItemMap[position]);
+            item.setName(mCursor.getString(Browser.HISTORY_PROJECTION_TITLE_INDEX));
+            String url = mCursor.getString(Browser.HISTORY_PROJECTION_URL_INDEX);
+            item.setUrl(url);
+            item.setFavicon((Bitmap) mUrlsToIcons.get(url));
+            return item;
+        }
+        
+        View getHeaderView(int position, View convertView) {
+            TextView item;
+            if (null == convertView || !(convertView instanceof TextView)) {
+                LayoutInflater factory = 
+                        LayoutInflater.from(BrowserHistoryPage.this);
+                item = (TextView) 
+                        factory.inflate(android.R.layout.preference_category, null);
+            } else {
+                item = (TextView) convertView;
+            }
+            item.setText(mDateSorter.getLabel(
+                    mItemMap[position] + DateSorter.DAY_COUNT));
+            return item;
+        }
+
+        public boolean areAllItemsEnabled() {
+            return false;
+        }
+
+        public boolean isEnabled(int position) {
+            return mItemMap[position] >= 0;
+        }
+
+        public int getCount() {
+            return mItemMap.length;
+        }
+
+        public Object getItem(int position) {
+            return null;
+        }
+
+        public long getItemId(int position) {
+            return mItemMap[position];
+        }
+
+        // 0 for TextView, 1 for HistoryItem
+        public int getItemViewType(int position) {
+            return mItemMap[position] < 0 ? 0 : 1;
+        }
+
+        public int getViewTypeCount() {
+            return 2;
+        }
+
+        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() == 1;
+        }
+    }
+}
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..b8bc495
--- /dev/null
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -0,0 +1,141 @@
+/*
+ * 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)) );
+        
+        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;
+            
+            if (value.length() > 0) {
+                Uri path = Uri.parse(value);
+                if (path.getScheme() == null) {
+                    value = "http://"+value;
+                    
+                    pref.setSummary(value);
+                    
+                    // 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;
+                }
+            }
+            
+            pref.setSummary(value);
+            return true;
+        } else if (pref.getKey().equals(BrowserSettings.PREF_TEXT_SIZE)) {
+            pref.setSummary(getVisualTextSizeName((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..4f456e7
--- /dev/null
+++ b/src/com/android/browser/BrowserProvider.java
@@ -0,0 +1,566 @@
+/*
+ * 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.SearchManager;
+import android.content.ContentProvider;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.UriMatcher;
+import android.database.AbstractCursor;
+import android.database.ContentObserver;
+import android.database.Cursor;
+import android.database.DataSetObserver;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteDatabase;
+import android.net.Uri;
+import android.provider.Browser;
+import android.util.Log;
+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 = "date DESC";
+
+    private static final String[] TABLE_NAMES = new String[] {
+        "bookmarks", "searches"
+    };
+    private static final String[] SUGGEST_PROJECTION = new String [] {
+        "0 AS " + SearchManager.SUGGEST_COLUMN_FORMAT,
+        "url AS " + SearchManager.SUGGEST_COLUMN_INTENT_DATA,
+        "url AS " + SearchManager.SUGGEST_COLUMN_TEXT_1,
+        "title AS " + SearchManager.SUGGEST_COLUMN_TEXT_2,
+        "_id"
+    };
+    private static final String SUGGEST_SELECTION = 
+            "url LIKE ? OR url LIKE ? OR url LIKE ? OR url LIKE ?";
+    private String[] SUGGEST_ARGS = new String[4];
+
+    // 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 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) {
+                    db.execSQL("INSERT INTO bookmarks (title, url, visits, " +
+                            "date, created, bookmark)" + " VALUES('" +
+                            bookmarks[i] + "', '" + bookmarks[i + 1] + 
+                            "', 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 add "Google Search"
+     */
+    private class MySuggestionCursor extends AbstractCursor {
+        private Cursor  mCursor;
+        private boolean mBeyondCursor;
+        private String  mString;
+        private Uri     mNotifyUri;
+        private ContentResolver mContentResolver;
+        private AbstractCursor.SelfContentObserver mObserver;
+        private final Object mObserverLock = new Object();
+
+        public MySuggestionCursor(Cursor c, String string) {
+            mCursor = c;
+            if (Regex.WEB_URL_PATTERN.matcher(string).matches()) {
+                mString = "";
+            } else {
+                mString = string;
+            }
+            mBeyondCursor = false;
+        }
+
+        public boolean onMove(int oldPosition, int newPosition) {
+            if (mCursor.getCount() == newPosition) {
+                mBeyondCursor = true;
+            } else {
+                mCursor.moveToPosition(newPosition);
+                mBeyondCursor = false;
+            }
+            return true;
+        }
+
+        public int getCount() {
+            if (mString.length() > 0) {
+                return mCursor.getCount() + 1;
+            } else {
+                return mCursor.getCount();
+            }
+        }
+
+        public boolean deleteRow() {
+            return !mBeyondCursor && mCursor.deleteRow();
+        }
+
+        public String[] getColumnNames() {
+            return mCursor.getColumnNames();
+        }
+
+        public int getColumnCount() {
+            return mCursor.getColumnCount();
+        }
+
+        public String getString(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getString(columnIndex);
+            }
+            switch (columnIndex) {
+                case 2: // SearchManager.SUGGEST_COLUMN_TEXT_1
+                    return "Google Search for \"" + mString + "\"";
+                case 1: // SearchManager.SUGGEST_COLUMN_INTENT_DATA
+                    return BrowserActivity.composeSearchUrl(mString);
+                case 3: // SearchManager.SUGGEST_COLUMN_TEXT_2
+                default:
+                    return "";
+            }
+        }
+
+        public short getShort(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getShort(columnIndex);
+            }
+            if (0 == columnIndex) {
+                return 0;
+            }
+            return -1;
+        }
+
+        public int getInt(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getInt(columnIndex);
+            }
+            if (0 == columnIndex) {
+                return 0;
+            }
+            return -1;
+        }
+
+        public long getLong(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getLong(columnIndex);
+            }
+            if (0 == columnIndex) {
+                return 0;
+            }
+            return -1;
+        }
+
+        public float getFloat(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getFloat(columnIndex);
+            }
+            if (0 == columnIndex) {
+                return 0f;
+            }
+            return -1f;
+        }
+
+        public double getDouble(int columnIndex) {
+            if (!mBeyondCursor) {
+                return mCursor.getDouble(columnIndex);
+            }
+            if (0 == columnIndex) {
+                return 0.0;
+            }
+            return -1.0;
+        }
+
+        public boolean isNull(int columnIndex) {
+            return mCursor.isNull(columnIndex);
+        }
+
+        public boolean supportsUpdates() {
+            return false;
+        }
+
+        public boolean hasUpdates() {
+            return false;
+        }
+
+        public boolean updateString(int columnIndex, String value) {
+            return false;
+        }
+
+        public boolean updateShort(int columnIndex, short value) {
+            return false;
+        }
+
+        public boolean updateInt(int columnIndex, int value) {
+            return false;
+        }
+
+        public boolean updateLong(int columnIndex, long value) {
+            return false;
+        }
+
+        public boolean updateFloat(int columnIndex, float value) {
+            return false;
+        }
+
+        public boolean updateDouble(int columnIndex, double value) {
+            return false;
+        }
+
+        // TODO Temporary change, finalize after jq's changes go in
+        public void deactivate() {
+            if (mCursor != null) {
+                mCursor.deactivate();
+            }
+            super.deactivate();
+        }
+
+        public boolean requery() {
+            return mCursor.requery();
+        }
+
+        // TODO Temporary change, finalize after jq's changes go in
+        public void close() {
+            super.close();
+            if (mCursor != null) {
+                mCursor.close();
+                mCursor = null;
+            }
+        }
+
+        public void registerContentObserver(ContentObserver observer) {
+            super.registerContentObserver(observer);
+        }
+
+        public void unregisterContentObserver(ContentObserver observer) {
+            super.unregisterContentObserver(observer);
+        }
+
+        public void registerDataSetObserver(DataSetObserver observer) {
+            super.registerDataSetObserver(observer);
+        }
+
+        public void unregisterDataSetObserver(DataSetObserver observer) {
+            super.unregisterDataSetObserver(observer);
+        }
+
+        protected void onChange(boolean selfChange) {
+            synchronized (mObserverLock) {
+                super.onChange(selfChange);
+                if (mNotifyUri != null && selfChange) {
+                    mContentResolver.notifyChange(mNotifyUri, mObserver);
+                }
+            }
+        }
+
+        public void setNotificationUri(ContentResolver cr, Uri uri) {
+            synchronized (mObserverLock) {
+                if (mObserver != null) {
+                    cr.unregisterContentObserver(mObserver);
+                }
+                mObserver = new AbstractCursor.SelfContentObserver(this);
+                cr.registerContentObserver(uri, true, mObserver);
+                mCursor.setNotificationUri(cr, uri);
+                super.setNotificationUri(cr, uri);
+                mContentResolver = cr;
+                mNotifyUri = uri;
+            }
+        }
+
+        public boolean getWantsAllOnMoveCalls() {
+            return mCursor.getWantsAllOnMoveCalls();
+        }
+    }
+
+    @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] + "%";
+                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;
+            }
+            // Suggestions are always performed with the default sort order:
+            // date ASC.
+            Cursor c = db.query(TABLE_NAMES[URI_MATCH_BOOKMARKS],
+                    SUGGEST_PROJECTION, suggestSelection, myArgs, null, null,
+                    ORDER_BY, null);
+            c.setNotificationUri(getContext().getContentResolver(), url);
+            return new MySuggestionCursor(c, 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/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
new file mode 100644
index 0000000..b19c02e
--- /dev/null
+++ b/src/com/android/browser/BrowserSettings.java
@@ -0,0 +1,431 @@
+/*
+ * 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.view.WindowManager;
+import android.webkit.CacheManager;
+import android.webkit.CookieManager;
+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";
+    private boolean loginInitialized = false;
+    private int orientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+    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";
+    
+    // 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);
+            s.setUserAgent(b.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);
+        }
+    }
+   
+    /**
+     * 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()));
+        orientation = p.getInt("orientation", orientation);
+        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;
+        }
+        
+        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"));
+        }
+        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 int getOrientation() {
+        return orientation;
+    }
+    
+    public void setOrientation(Context context, int o) {
+        if (orientation == o) {
+            return;
+        }
+        orientation = o;
+        Editor ed = PreferenceManager.
+                getDefaultSharedPreferences(context).edit();      
+        ed.putInt("orientation", orientation);
+        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;
+    }
+
+    /**
+     * 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) {
+            mTabControl.getCurrentWebView().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);
+        // Delete back-forward list
+        if (mTabControl != null) {
+            mTabControl.clearHistory();
+        }
+    }
+
+    /* 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/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..200f86a
--- /dev/null
+++ b/src/com/android/browser/FakeWebView.java
@@ -0,0 +1,106 @@
+/*
+ * 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 boolean        mUsesResource;
+
+    private class Listener implements WebView.PictureListener {
+        public void onNewPicture(WebView view, Picture 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) {
+                    Picture p = w.capturePicture();
+                    canvas.save();
+                    float scale = getWidth() * w.getScale() / w.getWidth();
+                    canvas.scale(scale, scale);
+                    canvas.translate(-w.getScrollX(), -w.getScrollY());
+                    canvas.drawPicture(p);
+                    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();
+            t.getWebView().setPictureListener(l);
+            if (t.getSubWebView() != null) {
+                t.getSubWebView().setPictureListener(l);
+            }
+        }
+    }
+}
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
new file mode 100644
index 0000000..42447e3
--- /dev/null
+++ b/src/com/android/browser/FindDialog.java
@@ -0,0 +1,243 @@
+/*
+ * 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.os.Handler;
+import android.os.Message;
+import android.text.Editable;
+import android.text.Spannable;
+import android.text.TextWatcher;
+import android.view.KeyEvent;
+import android.view.MotionEvent;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.LayoutInflater;
+import android.webkit.WebView;
+import android.widget.EditText;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/* package */ class FindDialog extends LinearLayout 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;
+
+    // Tags for messages to be sent to the handler.
+    private final static int FIND_RESPONSE  = 0;
+    private final static int NUM_FOUND      = 1;
+
+    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");
+            }
+            // Find is disabled for version 1.0, so find methods on WebView are
+            // currently private.
+            //mWebView.findPrevious(mEditText.getText().toString(),
+            //        mFindHandler.obtainMessage(FIND_RESPONSE));
+        }
+    };
+    
+    private Handler mFindHandler = new Handler() {
+        public void handleMessage(Message msg) {
+            if (NUM_FOUND == msg.what) {
+                mMatches.setText(Integer.toString(msg.arg1));
+                if (0 == msg.arg1) {
+                    disableButtons();
+                } else {
+                    mPrevButton.setFocusable(true);
+                    mNextButton.setFocusable(true);
+                    mPrevButton.setEnabled(true);
+                    mNextButton.setEnabled(true);
+                }
+            }
+        }
+    };
+    
+    private void disableButtons() {
+        mPrevButton.setEnabled(false);
+        mNextButton.setEnabled(false);
+        mPrevButton.setFocusable(false);
+        mNextButton.setFocusable(false);
+    }
+
+    public void setWebView(WebView webview) {
+        mWebView = webview;
+    }
+
+    /* package */ FindDialog(BrowserActivity context) {
+        super(context);
+        mBrowserActivity = context;
+        LayoutInflater factory = LayoutInflater.from(context);
+        factory.inflate(R.layout.browser_find, this);
+        
+        setLayoutParams(new ViewGroup.LayoutParams(
+                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);
+        disableButtons();
+    }
+    
+    public void dismiss() {
+        mBrowserActivity.closeFind();
+        // If the nav buttons are highlighted, then there are matches
+        // highlighted in the WebView, and they should be cleared.
+        if (mPrevButton.isEnabled()) {
+            // Find is disabled for version 1.0, so find methods on WebView are
+            // currently private.
+            //mWebView.clearMatches();
+        }
+    }
+    
+    @Override
+    public boolean dispatchKeyEvent(KeyEvent event) {
+        // Make up and down find previous/next
+        int code = event.getKeyCode();
+        boolean up = event.getAction() == KeyEvent.ACTION_UP;
+        switch (code) {
+            case KeyEvent.KEYCODE_BACK:
+                if (up) {
+                    dismiss();
+                }
+                return true;
+            case KeyEvent.KEYCODE_DPAD_UP:
+                if (event.getMetaState() != 0) {
+                    break;
+                }
+                if (up) {
+                    mFindPreviousListener.onClick(null);
+                }
+                return true;
+            case KeyEvent.KEYCODE_DPAD_DOWN:
+                if (event.getMetaState() != 0) {
+                    break;
+                }
+                if (up) {
+                    mFindListener.onClick(null);
+                }
+                return true;
+            case KeyEvent.KEYCODE_DPAD_CENTER:
+            case KeyEvent.KEYCODE_ENTER:
+                if (!mEditText.hasFocus()) {
+                    break;
+                }
+                if (up) {
+                    findNext();
+                }
+                return true;
+            default:
+                break;
+        }
+        return super.dispatchKeyEvent(event);
+    }
+    
+    @Override
+    public boolean dispatchTouchEvent(MotionEvent ev) {
+        super.dispatchTouchEvent(ev);
+        // Return true so that BrowserActivity thinks we handled it and does
+        // not dismiss us.
+        return true;
+    }
+
+    private void findNext() {
+        if (mWebView == null) {
+            throw new AssertionError("No WebView for FindDialog::findNext");
+        }
+        // Find is disabled for version 1.0, so find methods on WebView are
+        // currently private.
+        //mWebView.findNext(mEditText.getText().toString(),
+        //        mFindHandler.obtainMessage(FIND_RESPONSE));
+    }
+    
+    public void 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) {
+        CharSequence find = mEditText.getText();
+        if (0 == find.length()) {
+            disableButtons();
+            // Find is disabled for version 1.0, so find methods on WebView are
+            // currently private.
+            //mWebView.clearMatches();
+            mMatches.setText(R.string.zero);
+        } else {
+            if (mWebView == null) {
+                throw new AssertionError(
+                        "No WebView for FindDialog::onTextChanged");
+            }
+            // Find is disabled for version 1.0, so find methods on WebView are
+            // currently private.
+            //mWebView.findAll(find.toString(),
+            //        mFindHandler.obtainMessage(NUM_FOUND));
+        }
+    }
+
+    public void afterTextChanged(Editable s) {
+    }
+}
diff --git a/src/com/android/browser/GearsDialog.java b/src/com/android/browser/GearsDialog.java
new file mode 100644
index 0000000..fd9e762
--- /dev/null
+++ b/src/com/android/browser/GearsDialog.java
@@ -0,0 +1,124 @@
+/*
+ * 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.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.View;
+import android.widget.Button;
+
+import android.graphics.Bitmap;
+import android.graphics.BitmapFactory;
+
+import android.webkit.WebView;
+import android.webkit.WebViewClient;
+import android.webkit.WebSettings;
+
+import android.view.KeyEvent;
+import android.view.ViewGroup.LayoutParams;
+
+import android.widget.LinearLayout;
+
+public class GearsDialog extends Activity {
+
+  private static final String TAG = "GearsDialog";
+
+  private WebView webview;
+
+  private String htmlContent;
+  private String dialogArguments;
+
+  @Override
+  public void onCreate(Bundle icicle) {
+    super.onCreate(icicle);
+    webview = new WebView(this);
+    webview.getSettings().setJavaScriptEnabled(true);
+    webview.addJavascriptInterface(this, "bridge");
+
+    setContentView(webview);
+    setTitle("Gears");
+  }
+
+  @Override
+  public void onStart() {
+    super.onStart();
+    loadHTML();
+  }
+
+  @Override
+  public void onConfigurationChanged(Configuration newConfig) {
+    super.onConfigurationChanged(newConfig);
+    Intent i = getIntent();
+    boolean inSettings = i.getBooleanExtra("inSettings", false);
+    // If we are called from the settings, we
+    // dismiss ourselve upon upon rotation
+    if (inSettings) {
+      GearsDialogService.signalFinishedDialog();
+      finish();
+    }
+  }
+
+  /**
+   * Load the HTML content in the WebView
+   */
+  private void loadHTML() {
+    Intent i = getIntent();
+    htmlContent = i.getStringExtra("htmlContent");
+    dialogArguments = i.getStringExtra("dialogArguments");
+    webview.loadDataWithBaseURL("", htmlContent, "text/html", "", "");
+  }
+
+  public boolean dispatchKeyEvent(KeyEvent event) {
+    if (event.getKeyCode() ==  KeyEvent.KEYCODE_BACK && event.isDown()) {
+      GearsDialogService.signalFinishedDialog();
+     }
+    return super.dispatchKeyEvent(event);
+  }
+
+  /**
+   * Returns a json-formatted string containing the information
+   * about the site.
+   * This method is accessible through the javascript bridge.
+   */
+  public String getDialogArguments() {
+    return dialogArguments;
+  }
+
+  /**
+   * Set the results string and closes the dialog.
+   * This method is accessible through the javascript bridge.
+   */
+  public void closeDialog(String results) {
+    GearsDialogService.closeDialog(results);
+    GearsDialogService.signalFinishedDialog();
+    finish();
+  }
+
+  /**
+   * Debug method outputting a message.
+   * This method is accessible through the javascript bridge.
+   */
+  public void log(String msg) {
+    Log.v(TAG, msg);
+  }
+}
diff --git a/src/com/android/browser/GearsDialogService.java b/src/com/android/browser/GearsDialogService.java
new file mode 100644
index 0000000..b92ff47
--- /dev/null
+++ b/src/com/android/browser/GearsDialogService.java
@@ -0,0 +1,96 @@
+/*
+ * 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.Service;
+import android.util.Log;
+import android.content.Intent;
+import android.os.IBinder;
+
+import android.content.Intent;
+import android.content.ContentValues;
+import android.content.ActivityNotFoundException;
+
+import java.util.concurrent.locks.Condition;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import java.lang.InterruptedException;
+
+public class GearsDialogService extends Service {
+  private static final String TAG = "GearsDialogService";
+  private final String DIALOG_PACKAGE = "com.android.browser";
+  private final String DIALOG_CLASS = DIALOG_PACKAGE + ".GearsDialog";
+
+  public static Lock lock = new ReentrantLock();
+  public static Condition dialogFinished = lock.newCondition();
+  public static String results = null;
+
+  @Override
+  public IBinder onBind(Intent intent) {
+    if (IGearsDialogService.class.getName().equals(intent.getAction())) {
+      return mBinder;
+    }
+    return null;
+  }
+
+  private final IGearsDialogService.Stub mBinder = new IGearsDialogService.Stub() {
+    public String showDialog(String htmlContent, String dialogArguments,
+          boolean inSettings) {
+      return GearsDialogService.this.showDialog(htmlContent, dialogArguments,
+                 inSettings);
+    }
+  };
+
+  public static void closeDialog(String res) {
+    results = res;
+  }
+
+  public static void signalFinishedDialog() {
+    lock.lock();
+    dialogFinished.signal();
+    lock.unlock();
+  }
+
+  /**
+   * Show a 'true' modal dialog displaying html content, necessary
+   * for Gears. The method starts the GearsDialog activity, passing
+   * the necessary parameters to it, and then wait until the activity
+   * is finished. When the dialog closes, it sets the variable results.
+   */
+  public String showDialog(String htmlContent, String dialogArguments,
+      boolean inSettings) {
+    try {
+      Intent intent = new Intent();
+      intent.setClassName(DIALOG_PACKAGE, DIALOG_CLASS);
+      intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+      intent.putExtra("htmlContent", htmlContent);
+      intent.putExtra("dialogArguments", dialogArguments);
+      intent.putExtra("inSettings", inSettings);
+      lock.lock();
+      startActivity(intent);
+      dialogFinished.await();
+    } catch (InterruptedException e) {
+      Log.e(TAG, "exception e: " + e);
+    } catch (ActivityNotFoundException e) {
+      Log.e(TAG, "exception e: " + e);
+    } finally {
+      lock.unlock();
+    }
+    return results;
+  }
+}
diff --git a/src/com/android/browser/HistoryItem.java b/src/com/android/browser/HistoryItem.java
new file mode 100644
index 0000000..c83ced1
--- /dev/null
+++ b/src/com/android/browser/HistoryItem.java
@@ -0,0 +1,126 @@
+/*
+ * 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.graphics.Color;
+import android.graphics.drawable.BitmapDrawable;
+import android.graphics.drawable.Drawable;
+import android.graphics.drawable.LayerDrawable;
+import android.graphics.drawable.PaintDrawable;
+import android.view.LayoutInflater;
+import android.widget.LinearLayout;
+import android.widget.TextView;
+
+/**
+ *  Layout representing a history item in the classic history viewer.
+ */
+/* package */ class HistoryItem extends LinearLayout {
+
+    private TextView    mTitleView; // Truncated Title
+    private String      mUrl;       // Full Url
+    private TextView    mUrlText;   // Truncated Url
+    
+    /**
+     *  Create a new HistoryItem.
+     *  @param context  Context for this HistoryItem.
+     */
+    /* package */ HistoryItem(Context context) {
+        super(context);
+
+        setWillNotDraw(false);
+        LayoutInflater factory = LayoutInflater.from(context);
+        factory.inflate(R.layout.history_item, this);
+        mTitleView = (TextView) findViewById(R.id.title);
+        mUrlText = (TextView) findViewById(R.id.url);
+    }
+    
+    void copyTo(HistoryItem item) {
+        item.mTitleView.setText(mTitleView.getText());
+        item.mUrlText.setText(mUrlText.getText());
+    }
+    
+    /**
+     * Return the name of this HistoryItem.
+     * @return  String name of this HistoryItem.
+     /
+    /* package */ String getName() {
+        return mTitleView.getText().toString();
+    }
+
+    /**
+     * Return the url of this HistoryItem.
+     * @return  String url of this HistoryItem.
+     /
+    /* 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) {
+        Drawable[] array = new Drawable[2];
+        PaintDrawable p = new PaintDrawable(Color.WHITE);
+        p.setCornerRadius(3f);
+        array[0] = p;
+        if (b != null) {
+            array[1] = new BitmapDrawable(b);
+        } else {
+            array[1] = new BitmapDrawable(mContext.getResources().
+                    openRawResource(R.drawable.app_web_browser_sm));
+        }
+        LayerDrawable d = new LayerDrawable(array);
+        d.setLayerInset(1, 2, 2, 2, 2);
+        d.setBounds(0, 0, 20, 20);
+        mTitleView.setCompoundDrawables(d, null, null, null);
+    }
+    
+    /**
+     *  Set the name for this HistoryItem.
+     *  If the name is longer that BrowserSettings.MAX_TEXTVIEW_LEN characters, 
+     *  the name is truncated to BrowserSettings.MAX_TEXTVIEW_LEN characters. 
+     *  The History activity does not expose a UI element that can show the 
+     *  full title.
+     *  @param  name String representing new name for this HistoryItem.
+     */
+    /* package */ void setName(String name) {
+        if (name != null && name.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
+            name = name.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN);
+        }
+        mTitleView.setText(name);
+    }
+    
+    /**
+     *  Set the url for this HistoryItem.
+     *  @param  url String representing new url for this HistoryItem.
+     */
+    /* package */ void setUrl(String url) {
+        mUrl = url;
+        // Truncate the url for the screen
+        if (url.length() > BrowserSettings.MAX_TEXTVIEW_LEN) {
+            mUrlText.setText(url.substring(0, BrowserSettings.MAX_TEXTVIEW_LEN));
+        } else {
+            mUrlText.setText(url);
+        }
+    }
+}
diff --git a/src/com/android/browser/IGearsDialogService.aidl b/src/com/android/browser/IGearsDialogService.aidl
new file mode 100644
index 0000000..02b30a2
--- /dev/null
+++ b/src/com/android/browser/IGearsDialogService.aidl
@@ -0,0 +1,6 @@
+package com.android.browser;
+
+interface IGearsDialogService {
+  String showDialog(String htmlContent, String dialogArguments,
+             boolean inSettings);
+}
diff --git a/src/com/android/browser/ImageAdapter.java b/src/com/android/browser/ImageAdapter.java
new file mode 100644
index 0000000..e6eaa75
--- /dev/null
+++ b/src/com/android/browser/ImageAdapter.java
@@ -0,0 +1,298 @@
+/*
+ * 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.DialogInterface;
+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.content.Context;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.webkit.WebView;
+import android.widget.*;
+
+import java.util.ArrayList;
+
+/**
+ * Adapter used by ImageGrid.
+ */
+public class ImageAdapter implements ListAdapter {
+    
+    ArrayList<TabControl.Tab> mItems;  // Items shown in the grid
+    ArrayList<DataSetObserver> mDataObservers; // Data change listeners
+    Context mContext;  // Context to use to inflate views
+    boolean mMaxedOut;
+    boolean mLandScape;
+    ImageGrid mImageGrid;
+    boolean mIsLive;
+
+    ImageAdapter(Context context, ImageGrid grid,
+            ArrayList<TabControl.Tab> items, boolean live) {
+        mContext = context;
+        mIsLive = live;
+        if (items == null) {
+            mItems = new ArrayList<TabControl.Tab>();
+        } else {
+            mItems = items;
+            if (items.size() == TabControl.MAX_TABS) {
+                mMaxedOut = true;
+            }
+        }
+        mImageGrid = grid;
+        mDataObservers = new ArrayList<DataSetObserver>();
+        mLandScape = context.getResources().getConfiguration().orientation ==
+                Configuration.ORIENTATION_LANDSCAPE;
+    }
+    
+    /**
+     *  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' for a single tab or if the tab picker isn't
+            // "live" (meaning the user cannot click on a tab)
+            if (mItems.size() == 1 || !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);
+        }
+        if (mLandScape) {
+            ViewGroup.LayoutParams lp = img.getLayoutParams();
+            lp.width = 225;
+            lp.height = 120;
+            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(R.drawable.ssl_icon)
+                .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..e0a5c89
--- /dev/null
+++ b/src/com/android/browser/ImageGrid.java
@@ -0,0 +1,239 @@
+/*
+ * 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;
+    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);
+        }
+        if (Config.DEBUG && l == null) {
+            throw new AssertionError();
+        }
+        mListener = l;
+
+        mAdapter = new ImageAdapter(context, this, null, live);
+        setAdapter(mAdapter);
+
+        // android.R.color.window_background seems to return transparent?
+//        setBackgroundColor(android.R.color.window_background);
+        setBackgroundColor(0xFF000000);
+
+        setPadding(0, 10, 0, 10);
+        setVerticalSpacing(10);
+        setHorizontalSpacing(10);
+        setNumColumns(2);
+        setStretchMode(GridView.STRETCH_COLUMN_WIDTH);
+    }
+
+    @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());
+
+            // If we only have one active tab left, don't add the remove option
+            if (mAdapter.mItems.size() <= 1) {
+                menu.findItem(R.id.remove_tab_menu_id).setVisible(false);
+            }
+        }
+    }
+
+    // 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.  Replace the adapter with one
+        // that has the appropriate dimensions.
+        mAdapter = new ImageAdapter(mContext, this, mAdapter.mItems, mIsLive);
+        setAdapter(mAdapter);
+        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/TabControl.java b/src/com/android/browser/TabControl.java
new file mode 100644
index 0000000..66adf3c
--- /dev/null
+++ b/src/com/android/browser/TabControl.java
@@ -0,0 +1,840 @@
+/*
+ * 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.os.Bundle;
+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.JsPromptResult;
+import android.webkit.JsResult;
+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.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);
+        }
+    }
+    // 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);
+        }
+        // JavaScript functions
+        @Override
+        public boolean onJsAlert(WebView view, String url, String message,
+                JsResult result) {
+            return mClient.onJsAlert(view, url, message, result);
+        }
+        @Override
+        public boolean onJsConfirm(WebView view, String url, String message,
+                JsResult result) {
+            return mClient.onJsConfirm(view, url, message, result);
+        }
+        @Override
+        public boolean onJsPrompt(WebView view, String url, String message,
+                String initValue, JsPromptResult result) {
+            return mClient.onJsPrompt(view, url, message, initValue, result);
+        }
+        @Override
+        public boolean onJsBeforeUnload(WebView view, String url,
+                String message, JsResult result) {
+            return mClient.onJsBeforeUnload(view, url, message, result);
+        }
+    }
+    // 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;
+
+        // Construct a new tab
+        private Tab(WebView w) {
+            mMainView = w;
+        }
+
+        /**
+         * 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;
+        }
+        
+        /**
+         * 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;
+        }
+    };
+
+    /**
+     * 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));
+    }
+
+    /**
+     * 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() {
+        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);
+        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);
+        // 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";
+
+    /**
+     * 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();
+                    // 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);
+                    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);
+                }
+            }
+        }
+        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();
+        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);
+
+            // 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);
+            }
+
+            // 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;
+        }
+        t.mSavedState = null;
+        t.mUrl = null;
+        t.mTitle = null;
+        return true;
+    }
+}
