diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 5c2764b..244a903 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -274,371 +274,6 @@
                     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 static 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 static int BUFSIZE = 4096;
-        boolean mDoOverwrite = false;
-        String pluginsPath;
-        Context mContext;
-
-        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 (LOGV_ENABLED) {
-                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 (LOGV_ENABLED) {
-            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() {
-          FileInputStream iStream = null;
-          FileOutputStream oStream = null;
-          try {
-            if (LOGV_ENABLED) {
-              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);
-            iStream = new FileInputStream(buildInfoFile);
-            oStream = new FileOutputStream(buildInfoPlugins);
-            copyStreams(iStream, oStream);
-          } catch (IOException e) {
-            Log.e(TAG, "Exception while copying the build infos: " + e);
-          } finally {
-            try {
-              if (iStream != null) {
-                iStream.close();
-              }
-            } catch (IOException e2) {
-              Log.e(TAG, "Exception while closing the input stream: " + e2);
-            }
-            try {
-              if (oStream != null) {
-                oStream.close();
-              }
-            } catch (IOException e3) {
-              Log.e(TAG, "Exception while closing the output stream: " + e3);
-            }
-          }
-        }
-
-        /**
-         * 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 (LOGV_ENABLED) {
-                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 (LOGV_ENABLED) {
-                  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 (LOGV_ENABLED) {
-                  Log.v(TAG, "checkIsDifferentVersions(): extracted file "
-                    + path + " does not exist, we have a different version");
-                }
-                return true;
-              }
-            }
-          } catch (IOException e) {
-            Log.e(TAG, "Exception in checkDifferentVersions(): " + e);
-          }
-          return false;
-        }
-
-        /**
-         * Copy every files from the assets/plugins directory
-         * to the app_plugins directory in the data partition.
-         * Once copied, we copy over the SYSTEM_BUILD_INFOS file
-         * in the plugins directory.
-         *
-         * NOTE: we directly access the content from the Browser
-         * package (it's a zip file) and do not use AssetManager
-         * as there is a limit of 1Mb (see Asset.h)
-         */
-        public void run() {
-            // Lower the priority
-            Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
-            try {
-                if (pluginsPath == null) {
-                    Log.e(TAG, "No plugins path found!");
-                    return;
-                }
-
-                ZipFile zip = new ZipFile(APK_PATH);
-                Vector<ZipEntry> files = pluginsFilesFromZip(zip);
-                Vector<File> plugins = new Vector<File>();
-                int zipFilterLength = ZIP_FILTER.length();
-
-                Enumeration entries = files.elements();
-                while (entries.hasMoreElements()) {
-                    ZipEntry entry = (ZipEntry) entries.nextElement();
-                    String path = entry.getName().substring(zipFilterLength);
-                    File outputFile = new File(pluginsPath, path);
-                    outputFile.getParentFile().mkdirs();
-
-                    if (outputFile.exists() && !mDoOverwrite) {
-                        if (LOGV_ENABLED) {
-                            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 (LOGV_ENABLED) {
-                            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 (LOGV_ENABLED) {
-                        Log.v(TAG, "rename " + sourceFile.getPath()
-                            + " to " + renamedFile.getPath());
-                    }
-                    sourceFile.renameTo(renamedFile);
-                }
-
-                copyBuildInfos();
-            } catch (IOException e) {
-                Log.e(TAG, "IO Exception: " + e);
-            }
-        }
-    };
-
-    /**
-     * Copy the content of assets/plugins/ to the app_plugins directory
-     * in the data partition.
-     *
-     * This function is called every time the browser is started.
-     * We first check if the system image is newer than the one that
-     * copied the plugins (if there's plugins in the data partition).
-     * If this is the case, we then check if the versions are different.
-     * If they are different, we clean the plugins directory in the
-     * data partition, then start a thread to copy the plugins while
-     * the browser continue to load.
-     *
-     * @param overwrite if true overwrite the files even if they are
-     * already present (to let the user "reset" the plugins if needed).
-     */
-    private void copyPlugins(boolean overwrite) {
-        CopyPlugins copyPluginsFromAssets = new CopyPlugins(overwrite, this);
-        copyPluginsFromAssets.initPluginsPath();
-        if (copyPluginsFromAssets.newSystemImage())  {
-          if (copyPluginsFromAssets.checkIsDifferentVersions()) {
-            copyPluginsFromAssets.cleanPluginsDirectory();
-            Thread copyplugins = new Thread(copyPluginsFromAssets);
-            copyplugins.setName("CopyPlugins");
-            copyplugins.start();
-          }
-        }
-    }
-
     private static class ClearThumbnails extends AsyncTask<File, Void, Void> {
         @Override
         public Void doInBackground(File... files) {
@@ -845,7 +480,6 @@
                     && !mSettings.isLoginInitialized()) {
                 setupHomePage();
             }
-            copyPlugins(true);
 
             if (urlData.isEmpty()) {
                 if (mSettings.isLoginInitialized()) {
diff --git a/src/com/android/browser/BrowserPluginList.java b/src/com/android/browser/BrowserPluginList.java
deleted file mode 100644
index 6689b0e..0000000
--- a/src/com/android/browser/BrowserPluginList.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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
index 2348af0..ec3561f 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -30,13 +30,11 @@
 import android.preference.PreferenceScreen;
 import android.util.Log;
 import android.webkit.GeolocationPermissions;
-import android.webkit.Plugin;
 import android.webkit.WebStorage;
 import android.webkit.WebView;
 
 public class BrowserPreferencesPage extends PreferenceActivity
-        implements Preference.OnPreferenceChangeListener, 
-        Preference.OnPreferenceClickListener {
+        implements Preference.OnPreferenceChangeListener {
 
     String TAG = "BrowserPreferencesPage";
 
@@ -74,9 +72,6 @@
             addPreferencesFromResource(R.xml.debug_preferences);
         }
 
-        e = findPreference(BrowserSettings.PREF_GEARS_SETTINGS);
-        e.setOnPreferenceClickListener(this);
-
         PreferenceScreen websiteSettings = (PreferenceScreen)
             findPreference(BrowserSettings.PREF_WEBSITE_SETTINGS);
         Intent intent = new Intent(this, WebsiteSettingsActivity.class);
@@ -154,20 +149,6 @@
         
         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(
diff --git a/src/com/android/browser/BrowserSettings.java b/src/com/android/browser/BrowserSettings.java
index 6f5caed..aa54ccd 100644
--- a/src/com/android/browser/BrowserSettings.java
+++ b/src/com/android/browser/BrowserSettings.java
@@ -128,7 +128,6 @@
     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_WEBSITE_SETTINGS = "website_settings";
     public final static String PREF_TEXT_SIZE = "text_size";
     public final static String PREF_DEFAULT_ZOOM = "default_zoom";
diff --git a/src/com/android/browser/GearsBaseDialog.java b/src/com/android/browser/GearsBaseDialog.java
deleted file mode 100644
index 9a56cb8..0000000
--- a/src/com/android/browser/GearsBaseDialog.java
+++ /dev/null
@@ -1,473 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.res.Resources;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.os.Handler;
-import android.text.Spannable;
-import android.text.SpannableString;
-import android.text.style.UnderlineSpan;
-import android.util.Log;
-import android.view.InflateException;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.Button;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.io.InputStream;
-import java.io.IOException;
-import java.lang.ClassCastException;
-import java.net.HttpURLConnection;
-import java.net.MalformedURLException;
-import java.net.URL;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Base dialog class for gears
- */
-class GearsBaseDialog {
-
-  private static final String TAG = "GearsNativeDialog";
-  protected Handler mHandler;
-  protected Activity mActivity;
-  protected String mDialogArguments;
-
-  private Bitmap mIcon;
-  private static final int MAX_ICON_SIZE = 64;
-  protected int mChoosenIconSize;
-
-  // Dialog closing types
-  public static final int CANCEL = 0;
-  public static final int ALWAYS_DENY = 1;
-  public static final int ALLOW = 2;
-  public static final int DENY = 3;
-  public static final int NEW_ICON = 4;
-  public static final int UPDATE_ICON = 5;
-  public static final int REQUEST_ICON = 6;
-  public static final int PAUSE_REQUEST_ICON = 7;
-  public static final int CLEAR_REQUEST_ICON = 8;
-
-  protected final String LOCAL_DATA_STRING = "localData";
-  protected final String LOCAL_STORAGE_STRING = "localStorage";
-  protected final String LOCATION_DATA_STRING = "locationData";
-
-  protected String mGearsVersion = "UNDEFINED";
-  protected boolean mDebug = false;
-
-  public GearsBaseDialog(Activity activity, Handler handler, String arguments) {
-    mActivity = activity;
-    mHandler = handler;
-    mDialogArguments = arguments;
-  }
-
-  Resources getResources() {
-    return mActivity.getResources();
-  }
-
-  Object getSystemService(String name) {
-    return mActivity.getSystemService(name);
-  }
-
-  View findViewById(int id) {
-    return mActivity.findViewById(id);
-  }
-
-  private String getString(int id) {
-    return mActivity.getString(id);
-  }
-
-  public void setDebug(boolean debug) {
-    mDebug = debug;
-  }
-
-  public void setGearsVersion(String version) {
-    mGearsVersion = version;
-  }
-
-  public String closeDialog(int closingType) {
-    return null;
-  }
-
-  /*
-   * Utility methods for setting up the dialogs elements
-   */
-
-  /**
-   * Inflate a given layout in a view (which has to be
-   * a ViewGroup, e.g. LinearLayout).
-   * This is used to share the basic dialog outline among
-   * the different dialog types.
-   */
-  void inflate(int layout, int viewID) {
-    LayoutInflater inflater = (LayoutInflater) getSystemService(
-        Context.LAYOUT_INFLATER_SERVICE);
-    View view = findViewById(viewID);
-    if (view != null) {
-      try {
-        ViewGroup viewGroup = (ViewGroup) view;
-        inflater.inflate(layout, viewGroup);
-      } catch (ClassCastException e) {
-        String msg = "exception, the view (" + view + ")";
-        msg += " is not a ViewGroup";
-        Log.e(TAG, msg, e);
-      } catch (InflateException e) {
-        Log.e(TAG, "exception while inflating the layout", e);
-      }
-    } else {
-      String msg = "problem, trying to inflate a non-existent view";
-      msg += " (" + viewID + ")";
-      Log.e(TAG, msg);
-    }
-  }
-
-  /**
-   * Button setup.
-   * Set the button's text and its listener. If the text resource's id
-   * is 0, makes the button invisible.
-   */
-  void setupButton(int buttonRscID,
-                   int rscString,
-                   View.OnClickListener listener,
-                   boolean isLink,
-                   boolean requestFocus) {
-    View view = findViewById(buttonRscID);
-    if (view == null) {
-      return;
-    }
-
-    Button button = (Button) view;
-
-    if (rscString == 0) {
-      button.setVisibility(View.GONE);
-    } else {
-      CharSequence text = getString(rscString);
-      button.setText(text);
-      button.setOnClickListener(listener);
-      if (isLink) {
-        displayAsLink(button);
-      }
-      if (requestFocus) {
-        button.requestFocus();
-      }
-    }
-  }
-
-  /**
-   * Button setup: as the above method, except that 'isLink' and
-   * 'requestFocus' default to false.
-   */
-  void setupButton(int buttonRsc, int rsc,
-                   View.OnClickListener listener) {
-    setupButton(buttonRsc, rsc, listener, false, false);
-  }
-
-  /**
-   * Utility method to setup the three dialog buttons.
-   */
-  void setupButtons(int alwaysDenyRsc, int allowRsc, int denyRsc) {
-    setupButton(R.id.button_alwaysdeny, alwaysDenyRsc,
-                new Button.OnClickListener() {
-                  public void onClick(View v) {
-                    mHandler.sendEmptyMessage(ALWAYS_DENY);
-                  }
-                });
-
-    setupButton(R.id.button_allow, allowRsc,
-                new Button.OnClickListener() {
-                  public void onClick(View v) {
-                    mHandler.sendEmptyMessage(ALLOW);
-                  }
-                });
-
-    setupButton(R.id.button_deny, denyRsc,
-                new Button.OnClickListener() {
-                  public void onClick(View v) {
-                    mHandler.sendEmptyMessage(DENY);
-                  }
-                });
-  }
-
-  /**
-   * Display a button as an HTML link. Remove the background, set the
-   * text color to R.color.dialog_link and draw an underline
-   */
-  void displayAsLink(Button button) {
-    if (button == null) {
-      return;
-    }
-
-    CharSequence text = button.getText();
-    button.setBackgroundDrawable(null);
-    int color = getResources().getColor(R.color.dialog_link);
-    button.setTextColor(color);
-    SpannableString str = new SpannableString(text);
-    str.setSpan(new UnderlineSpan(), 0, str.length(),
-                Spannable.SPAN_INCLUSIVE_INCLUSIVE);
-    button.setText(str);
-    button.setFocusable(false);
-  }
-
-  /**
-   * Utility method to set elements' text indicated in
-   * the dialogs' arguments.
-   */
-  void setLabel(JSONObject json, String name, int rsc) {
-    try {
-      if (json.has(name)) {
-        String text = json.getString(name);
-        View view = findViewById(rsc);
-        if (view != null && text != null) {
-          TextView textView = (TextView) view;
-          textView.setText(text);
-          textView.setVisibility(View.VISIBLE);
-        }
-      }
-    } catch (JSONException e) {
-      Log.e(TAG, "json exception", e);
-    }
-  }
-
-  /**
-   * Utility method to hide a view.
-   */
-  void hideView(View v, int rsc) {
-    if (rsc == 0) {
-      return;
-    }
-    View view;
-    if (v == null) {
-      view = findViewById(rsc);
-    } else {
-      view = v.findViewById(rsc);
-    }
-    if (view != null) {
-      view.setVisibility(View.GONE);
-    }
-  }
-
-  /**
-   * Utility method to show a view.
-   */
-  void showView(View v, int rsc) {
-    if (rsc == 0) {
-      return;
-    }
-    View view;
-    if (v == null) {
-      view = findViewById(rsc);
-    } else {
-      view = v.findViewById(rsc);
-    }
-    if (view != null) {
-      view.setVisibility(View.VISIBLE);
-    }
-  }
-
-  /**
-   * Utility method to set a text.
-   */
-  void setText(View v, int rsc, CharSequence text) {
-    if (rsc == 0) {
-      return;
-    }
-    View view = v.findViewById(rsc);
-    if (view != null) {
-      TextView textView = (TextView) view;
-      textView.setText(text);
-      textView.setVisibility(View.VISIBLE);
-    }
-  }
-
-  /**
-   * Utility method to set a text.
-   */
-  void setText(View v, int rsc, int txtRsc) {
-    if (rsc == 0) {
-      return;
-    }
-    View view = v.findViewById(rsc);
-    if (view != null) {
-      TextView textView = (TextView) view;
-      if (txtRsc == 0) {
-        textView.setVisibility(View.GONE);
-      } else {
-        CharSequence text = getString(txtRsc);
-        textView.setText(text);
-        textView.setVisibility(View.VISIBLE);
-      }
-    }
-  }
-
-  /**
-   * Utility class to download an icon in the background.
-   * Once done ask the UI thread to update the icon.
-   */
-  class IconDownload implements Runnable {
-    private String mUrlString;
-
-    IconDownload(String url) {
-      mUrlString = url;
-    }
-
-    public void run() {
-      if (mUrlString == null) {
-        return;
-      }
-      try {
-        URL url = new URL(mUrlString);
-        HttpURLConnection connection = (HttpURLConnection) url.openConnection();
-        connection.setDoInput(true);
-        connection.connect();
-        InputStream is = connection.getInputStream();
-        Bitmap customIcon = BitmapFactory.decodeStream(is);
-        if (customIcon != null) {
-          mIcon = customIcon;
-          mHandler.sendEmptyMessage(UPDATE_ICON);
-        }
-      } catch (ClassCastException e) {
-        Log.e(TAG, "Class cast exception (" + mUrlString + ")", e);
-      } catch (MalformedURLException e) {
-        Log.e(TAG, "Malformed url (" + mUrlString + ") ", e);
-      } catch (IOException e) {
-        Log.e(TAG, "Exception downloading icon (" + mUrlString + ") ", e);
-      }
-    }
-  }
-
-  /**
-   * Utility method to update the icon.
-   * Called on the UI thread.
-   */
-  public void updateIcon() {
-    if (mIcon == null) {
-      return;
-    }
-    View view = findViewById(R.id.origin_icon);
-    if (view != null) {
-      ImageView imageView = (ImageView) view;
-      imageView.setMaxHeight(MAX_ICON_SIZE);
-      imageView.setMaxWidth(MAX_ICON_SIZE);
-      imageView.setScaleType(ImageView.ScaleType.FIT_XY);
-      imageView.setImageBitmap(mIcon);
-      imageView.setVisibility(View.VISIBLE);
-    }
-  }
-
-  /**
-   * Utility method to download an icon from a url and set
-   * it to the GUI element R.id.origin_icon.
-   * It is used both in the shortcut dialog and the
-   * permission dialog.
-   * The actual download is done in the background via
-   * IconDownload; once the icon is downlowded the UI is updated
-   * via updateIcon().
-   * The icon size is included in the layout with the choosen
-   * size, although not displayed, to limit text reflow once
-   * the icon is received.
-   */
-  void downloadIcon(String url) {
-    if (url == null) {
-      return;
-    }
-    View view = findViewById(R.id.origin_icon);
-    if (view != null) {
-      view.setMinimumWidth(mChoosenIconSize);
-      view.setMinimumHeight(mChoosenIconSize);
-      view.setVisibility(View.INVISIBLE);
-    }
-    Thread thread = new Thread(new IconDownload(url));
-    thread.start();
-  }
-
-  /**
-   * Utility method that get the dialogMessage
-   * and icon and ask the setupDialog(message,icon)
-   * method to set the values.
-   */
-  public void setupDialog() {
-    TextView dialogMessage = null;
-    ImageView icon = null;
-
-    View view = findViewById(R.id.dialog_message);
-    if (view != null) {
-      dialogMessage = (TextView) view;
-    }
-
-    View iconView = findViewById(R.id.icon);
-    if (iconView != null) {
-      icon = (ImageView) iconView;
-    }
-
-    if ((dialogMessage != null) && (icon != null)) {
-      setupDialog(dialogMessage, icon);
-      dialogMessage.setVisibility(View.VISIBLE);
-    }
-  }
-
-  /*
-   * Set the message and icon of the dialog
-   */
-  public void setupDialog(TextView message, ImageView icon) {
-    message.setText(R.string.unrecognized_dialog_message);
-    icon.setImageResource(R.drawable.ic_dialog_menu_generic);
-    message.setVisibility(View.VISIBLE);
-  }
-
-  /**
-   * Setup the dialog
-   * By default, just display a simple message.
-   */
-  public void setup() {
-    setupButtons(0, 0, R.string.default_button);
-    setupDialog();
-  }
-
-  /**
-   * Method called when the back button is pressed,
-   * allowing the dialog to intercept the default behaviour.
-   */
-  public boolean handleBackButton() {
-    return false;
-  }
-
-  /**
-   * Returns the resource string of the notification displayed
-   * after the dialog. By default, does not return one.
-   */
-  public int notification() {
-    return 0;
-  }
-
-  /**
-   * If a secondary dialog (e.g. a confirmation dialog) is created,
-   * GearsNativeDialog will call this method.
-   */
-  public Dialog onCreateDialog(int id) {
-    // This should be redefined by subclasses as needed.
-    return null;
-  }
-
-}
diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java
deleted file mode 100644
index 192108a..0000000
--- a/src/com/android/browser/GearsNativeDialog.java
+++ /dev/null
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.app.Dialog;
-import android.content.Intent;
-import android.net.Uri;
-import android.os.Bundle;
-import android.os.Handler;
-import android.os.Message;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.KeyEvent;
-import android.view.Window;
-import android.widget.BaseAdapter;
-import android.widget.Toast;
-
-import android.webkit.gears.NativeDialog;
-
-import com.android.browser.GearsBaseDialog;
-import com.android.browser.GearsPermissionsDialog;
-import com.android.browser.GearsSettingsDialog;
-
-/**
- * Native dialog Activity used by gears
- * TODO: rename in GearsNativeDialogActivity
- * @hide
- */
-public class GearsNativeDialog extends Activity {
-
-  private static final String TAG = "GearsNativeDialog";
-
-  private String mDialogArguments;
-
-  private String mGearsVersion = null;
-
-  private boolean mDebug = false;
-
-  private int mDialogType;
-  private static final int SETTINGS_DIALOG = 1;
-  private static final int PERMISSION_DIALOG = 2;
-  private static final int LOCATION_DIALOG = 3;
-
-  private static final String VERSION_STRING = "version";
-  private static final String SETTINGS_DIALOG_STRING = "settings_dialog";
-  private static final String PERMISSION_DIALOG_STRING = "permissions_dialog";
-  private static final String LOCATION_DIALOG_STRING = "locations_dialog";
-
-  private boolean mDialogDismissed = false;
-
-  GearsBaseDialog dialog;
-
-  // Handler for callbacks to the UI thread
-  final Handler mHandler = new Handler() {
-    public void handleMessage(Message msg) {
-      if (msg.what == GearsBaseDialog.NEW_ICON) {
-        BaseAdapter adapter = (BaseAdapter) msg.obj;
-        adapter.notifyDataSetChanged();
-      } else if (msg.what == GearsBaseDialog.UPDATE_ICON) {
-        dialog.updateIcon();
-      } else if (msg.what == GearsBaseDialog.ALWAYS_DENY) {
-        closeDialog(GearsBaseDialog.ALWAYS_DENY);
-      } else if (msg.what == GearsBaseDialog.ALLOW) {
-        closeDialog(GearsBaseDialog.ALLOW);
-      } else if (msg.what == GearsBaseDialog.DENY) {
-        closeDialog(GearsBaseDialog.DENY);
-      }
-      super.handleMessage(msg);
-    }
-  };
-
-  @Override
-  public void onCreate(Bundle icicle) {
-    getArguments();
-    if (mDialogType == SETTINGS_DIALOG) {
-      setTheme(android.R.style.Theme);
-    }
-    super.onCreate(icicle);
-    if (mDialogType != SETTINGS_DIALOG) {
-      requestWindowFeature(Window.FEATURE_NO_TITLE);
-      setContentView(R.layout.gears_dialog);
-    }
-
-    switch (mDialogType) {
-      case SETTINGS_DIALOG:
-        dialog = new GearsSettingsDialog(this, mHandler, mDialogArguments);
-        dialog.setGearsVersion(mGearsVersion);
-        break;
-      case PERMISSION_DIALOG:
-        dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
-        break;
-      case LOCATION_DIALOG:
-        dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
-        break;
-      default:
-        dialog = new GearsBaseDialog(this, mHandler, mDialogArguments);
-    }
-    dialog.setDebug(mDebug);
-    dialog.setup();
-  }
-
-  /**
-   * Get the arguments for the dialog
-   *
-   * The dialog needs a json string as an argument, as
-   * well as a dialogType. In debug mode the arguments
-   * are mocked.
-   */
-  private void getArguments() {
-    if (mDebug) {
-      mDialogType = LOCATION_DIALOG +1;
-      mockArguments();
-
-      return;
-    }
-
-    Intent intent = getIntent();
-    mDialogArguments = intent.getStringExtra("dialogArguments");
-    String dialogTypeString = intent.getStringExtra("dialogType");
-    if (dialogTypeString == null) {
-      return;
-    }
-
-    if (Browser.LOGV_ENABLED) {
-      Log.v(TAG, "dialogtype: " + dialogTypeString);
-    }
-
-    if (dialogTypeString.equalsIgnoreCase(SETTINGS_DIALOG_STRING)) {
-      mDialogType = SETTINGS_DIALOG;
-      mGearsVersion = intent.getStringExtra(VERSION_STRING);
-    } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) {
-      mDialogType = PERMISSION_DIALOG;
-    } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) {
-      mDialogType = LOCATION_DIALOG;
-    }
-  }
-
-  /**
-   * Utility method for debugging the dialog.
-   *
-   * Set mock arguments.
-   */
-  private void mockArguments() {
-
-    String argumentsPermissions = "{ locale: \"en-US\", "
-        + "origin: \"http://www.google.com\", dialogType: \"localData\","
-        + "customIcon: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/32.png\","
-        + "customName: \"My Application\","
-        + "customMessage: \"Press the button to enable my "
-        + "application to run offline!\" };";
-
-    String argumentsPermissions2 = "{ locale: \"en-US\", "
-        + "origin: \"http://www.google.com\", dialogType: \"localData\" };";
-
-    String argumentsLocation = "{ locale: \"en-US\", "
-        + "origin: \"http://www.google.com\", dialogType: \"locationData\","
-        + "customIcon: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/32.png\","
-        + "customName: \"My Application\","
-        + "customMessage: \"Press the button to enable my "
-        + "application to run offline!\" };";
-
-    String argumentsSettings = "{ locale: \"en-US\", permissions: [ { "
-        + "name: \"http://www.google.com\", "
-        + "localStorage: { permissionState: 0 }, "
-        + "locationData: { permissionState: 1 } }, "
-        + "{ name: \"http://www.aaronboodman.com\", "
-        + "localStorage: { permissionState: 1 }, "
-        + "locationData: { permissionState: 2 } }, "
-        + "{ name: \"http://www.evil.org\", "
-        + "localStorage: { permissionState: 2 }, "
-        + "locationData: { permissionState: 2 } } ] }";
-
-    switch (mDialogType) {
-      case PERMISSION_DIALOG:
-        mDialogArguments = argumentsPermissions;
-        break;
-      case LOCATION_DIALOG:
-        mDialogArguments = argumentsLocation;
-        break;
-      case SETTINGS_DIALOG:
-        mDialogArguments = argumentsSettings;
-        break;
-    }
-  }
-
-  /**
-   * Close the dialog and set the return string value.
-   */
-  private void closeDialog(int closingType) {
-    String ret = dialog.closeDialog(closingType);
-
-    if (mDebug) {
-      Log.v(TAG, "closeDialog ret value: " + ret);
-    }
-
-    NativeDialog.closeDialog(ret);
-    notifyEndOfDialog();
-    finish();
-
-    // If the dialog sets a notification, we display it.
-    int notification = dialog.notification();
-    if (notification != 0) {
-      Toast toast = Toast.makeText(this, notification, Toast.LENGTH_LONG);
-      toast.setGravity(Gravity.BOTTOM, 0, 0);
-      toast.show();
-    }
-  }
-
-  @Override
-  public void onDestroy() {
-    super.onDestroy();
-    // In case we reach this point without
-    // notifying NativeDialog, we do it now.
-    if (!mDialogDismissed) {
-      notifyEndOfDialog();
-    }
-  }
-
-  @Override
-  public void onPause(){
-    super.onPause();
-    if (!mDialogDismissed) {
-      closeDialog(GearsBaseDialog.CANCEL);
-    }
-  }
-
-  /**
-   * Signal to NativeDialog that we are done.
-   */
-  private void notifyEndOfDialog() {
-    NativeDialog.signalFinishedDialog();
-    mDialogDismissed = true;
-  }
-
-  /**
-   * Intercepts the back key to immediately notify
-   * NativeDialog that we are done.
-   */
-  public boolean dispatchKeyEvent(KeyEvent event) {
-    if ((event.getKeyCode() == KeyEvent.KEYCODE_BACK)
-      && (event.getAction() == KeyEvent.ACTION_DOWN)) {
-      if (!dialog.handleBackButton()) {
-        // if the dialog doesn't do anything with the back button
-        closeDialog(GearsBaseDialog.CANCEL);
-      }
-      return true; // event consumed
-    }
-    return super.dispatchKeyEvent(event);
-  }
-
-  /**
-   * If the dialog call showDialog() on ourself, we let
-   * it handle the creation of this secondary dialog.
-   * It is used in GearsSettingsDialog, to create the confirmation
-   * dialog when the user click on "Remove this site from Gears"
-   */
-  @Override
-  protected Dialog onCreateDialog(int id) {
-    return dialog.onCreateDialog(id);
-  }
-
-}
diff --git a/src/com/android/browser/GearsPermissions.java b/src/com/android/browser/GearsPermissions.java
deleted file mode 100644
index e48e045..0000000
--- a/src/com/android/browser/GearsPermissions.java
+++ /dev/null
@@ -1,196 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.util.Log;
-
-import java.util.HashMap;
-import java.util.Iterator;
-
-/**
- * The permission mechanism works the following way:
- *
- * PermissionType allows to define a type of permission
- *   (e.g. localStorage/locationData), storing a name and a set of
- *   resource ids corresponding to the GUI resources.
- *
- * Permission defines an actual permission instance, with a type and a value.
- *
- * OriginPermissions holds an origin with a set of Permission objects
- */
-class GearsPermissions {
-
-  private static final String TAG = "GearsPermissions";
-
-  /**
-   * Defines a type of permission
-   *
-   * Store the permission's name (used in the json result)
-   * Graphically, each permission is a label followed by two radio buttons.
-   * We store the resources ids here.
-   */
-  public static class PermissionType {
-    public static final int PERMISSION_NOT_SET = 0;
-    public static final int PERMISSION_ALLOWED = 1;
-    public static final int PERMISSION_DENIED = 2;
-
-    String mName;
-    int mTitleRsc;
-    int mSubtitleOnRsc;
-    int mSubtitleOffRsc;
-
-    PermissionType(String name) {
-      mName = name;
-    }
-
-    public void setResources(int titleRsc,
-        int subtitleOnRsc, int subtitleOffRsc) {
-      mTitleRsc = titleRsc;
-      mSubtitleOnRsc = subtitleOnRsc;
-      mSubtitleOffRsc = subtitleOffRsc;
-    }
-
-    public String getName() {
-      return mName;
-    }
-
-    public int getTitleRsc() {
-      return mTitleRsc;
-    }
-
-    public int getSubtitleOnRsc() {
-      return mSubtitleOnRsc;
-    }
-
-    public int getSubtitleOffRsc() {
-      return mSubtitleOffRsc;
-    }
-
-  }
-
-  /**
-   * Simple class to store an instance of a permission
-   *
-   * i.e. a permission type and a value
-   * Value can be either PERMISSION_NOT_SET,
-   * PERMISSION_ALLOWED or PERMISSION_DENIED
-   * (defined in PermissionType).
-   */
-  public static class Permission {
-    PermissionType mType;
-    int mValue;
-
-    Permission(PermissionType type, int value) {
-      mType = type;
-      mValue = value;
-    }
-
-    Permission(PermissionType type) {
-      mType = type;
-      mValue = 0;
-    }
-
-    public PermissionType getType() {
-      return mType;
-    }
-
-    public void setValue(int value) {
-      mValue = value;
-    }
-
-    public int getValue() {
-      return mValue;
-    }
-  }
-
-  /**
-   * Interface used by the GearsNativeDialog implementation
-   * to listen to changes in the permissions.
-   */
-  public interface PermissionsChangesListener {
-    public boolean setPermission(PermissionType type, int perm);
-  }
-
-  /**
-   * Holds the model for an origin -- each origin has a set of
-   * permissions.
-   */
-  public static class OriginPermissions {
-    HashMap<PermissionType, Permission> mPermissions;
-    String mOrigin;
-    public static PermissionsChangesListener mListener;
-
-    public static void setListener(PermissionsChangesListener listener) {
-      mListener = listener;
-    }
-
-    OriginPermissions(String anOrigin) {
-      mOrigin = anOrigin;
-      mPermissions = new HashMap<PermissionType, Permission>();
-    }
-
-    OriginPermissions(OriginPermissions perms) {
-      mOrigin = perms.getOrigin();
-      mPermissions = new HashMap<PermissionType, Permission>();
-      HashMap<PermissionType, Permission> permissions = perms.getPermissions();
-      Iterator<PermissionType> iterator = permissions.keySet().iterator();
-      while (iterator.hasNext()) {
-        Permission permission = permissions.get(iterator.next());
-        int value = permission.getValue();
-        setPermission(permission.getType(), value);
-      }
-    }
-
-    public String getOrigin() {
-      return mOrigin;
-    }
-
-    public HashMap<PermissionType, Permission> getPermissions() {
-      return mPermissions;
-    }
-
-    public int getPermission(PermissionType type) {
-      return mPermissions.get(type).getValue();
-    }
-
-    public void setPermission(PermissionType type, int perm) {
-      if (mPermissions.get(type) == null) {
-        Permission permission = new Permission(type, perm);
-        mPermissions.put(type, permission);
-        return;
-      }
-
-      if (mListener != null) {
-        mListener.setPermission(type, perm);
-      }
-
-      mPermissions.get(type).setValue(perm);
-    }
-
-    public void print() {
-      Log.v(TAG, "Permissions for " + mOrigin);
-      Iterator<PermissionType> iterator = mPermissions.keySet().iterator();
-      while (iterator.hasNext()) {
-        Permission permission = mPermissions.get(iterator.next());
-        String name = permission.getType().getName();
-        int value = permission.getValue();
-        Log.v(TAG, "  " + name + ": " + value);
-      }
-    }
-  }
-
-}
diff --git a/src/com/android/browser/GearsPermissionsDialog.java b/src/com/android/browser/GearsPermissionsDialog.java
deleted file mode 100644
index dbec363..0000000
--- a/src/com/android/browser/GearsPermissionsDialog.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.os.Handler;
-import android.util.Log;
-import android.view.Gravity;
-import android.view.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears permission dialog
- */
-class GearsPermissionsDialog extends GearsBaseDialog {
-
-  private static final String TAG = "GearsPermissionsDialog";
-
-  private String mDialogType;
-  private int mNotification = 0;
-
-  public GearsPermissionsDialog(Activity activity,
-                                Handler handler,
-                                String arguments) {
-    super (activity, handler, arguments);
-  }
-
-  public void setup() {
-    inflate(R.layout.gears_dialog_permission, R.id.panel_content);
-    setupButtons(R.string.permission_button_alwaysdeny,
-                 R.string.permission_button_allow,
-                 R.string.permission_button_deny);
-
-    try {
-      JSONObject json = new JSONObject(mDialogArguments);
-
-      if (json.has("dialogType")) {
-        mDialogType = json.getString("dialogType");
-        setupDialog();
-      }
-
-      if (!json.has("customName")) {
-        setLabel(json, "origin", R.id.origin_title);
-        View titleView = findViewById(R.id.origin_title);
-        if (titleView != null) {
-          TextView title = (TextView) titleView;
-          title.setGravity(Gravity.CENTER);
-        }
-      } else {
-        setLabel(json, "customName", R.id.origin_title);
-        setLabel(json, "origin", R.id.origin_subtitle);
-        setLabel(json, "customMessage", R.id.origin_message);
-      }
-
-      if (json.has("customIcon")) {
-        String iconUrl = json.getString("customIcon");
-        mChoosenIconSize = 32;
-        downloadIcon(iconUrl);
-      }
-
-      View msg = findViewById(R.id.permission_dialog_message);
-      if (msg != null) {
-        TextView dialogMessage = (TextView) msg;
-        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
-          dialogMessage.setText(R.string.query_data_message);
-        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
-          dialogMessage.setText(R.string.location_message);
-        }
-      }
-
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception ", e);
-    }
-  }
-
-  public void setupDialog(TextView message, ImageView icon) {
-    if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
-      message.setText(R.string.query_data_prompt);
-      icon.setImageResource(android.R.drawable.ic_popup_disk_full);
-    } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
-      message.setText(R.string.location_prompt);
-      icon.setImageResource(R.drawable.ic_dialog_menu_generic);
-    }
-  }
-
-  public String closeDialog(int closingType) {
-    String ret = null;
-    switch (closingType) {
-      case ALWAYS_DENY:
-        ret = "{\"allow\": false, \"permanently\": true }";
-        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
-          mNotification = R.string.storage_notification_alwaysdeny;
-        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
-          mNotification = R.string.location_notification_alwaysdeny;
-        }
-        break;
-      case ALLOW:
-        ret = "{\"allow\": true, \"permanently\": true }";
-        if (mDialogType.equalsIgnoreCase(LOCAL_DATA_STRING)) {
-          mNotification = R.string.storage_notification;
-        } else if (mDialogType.equalsIgnoreCase(LOCATION_DATA_STRING)) {
-          mNotification = R.string.location_notification;
-        }
-        break;
-      case DENY:
-        ret = "{\"allow\": false, \"permanently\": false }";
-        break;
-    }
-    return ret;
-  }
-
-  public int notification() {
-    return mNotification;
-  }
-}
diff --git a/src/com/android/browser/GearsSettingsDialog.java b/src/com/android/browser/GearsSettingsDialog.java
deleted file mode 100644
index 5ea2342..0000000
--- a/src/com/android/browser/GearsSettingsDialog.java
+++ /dev/null
@@ -1,460 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.browser;
-
-import android.app.Activity;
-import android.app.AlertDialog;
-import android.app.Dialog;
-import android.content.Context;
-import android.content.DialogInterface;
-import android.os.Handler;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ArrayAdapter;
-import android.widget.AdapterView;
-import android.widget.AdapterView.OnItemClickListener;
-import android.widget.BaseAdapter;
-import android.widget.Button;
-import android.widget.CheckBox;
-import android.widget.CompoundButton;
-import android.widget.ImageView;
-import android.widget.ListAdapter;
-import android.widget.ListView;
-import android.widget.RadioButton;
-import android.widget.TextView;
-
-import com.android.browser.GearsPermissions.OriginPermissions;
-import com.android.browser.GearsPermissions.Permission;
-import com.android.browser.GearsPermissions.PermissionsChangesListener;
-import com.android.browser.GearsPermissions.PermissionType;
-
-import java.util.Vector;
-import java.util.List;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears Settings dialog
- */
-class GearsSettingsDialog extends GearsBaseDialog
-    implements PermissionsChangesListener {
-
-  private static final String TAG = "GearsPermissionsDialog";
-  private Vector<OriginPermissions> mSitesPermissions = null;
-  private Vector<OriginPermissions> mOriginalPermissions = null;
-  private Vector<OriginPermissions> mCurrentPermissions = null;
-
-  private Vector<PermissionType> mPermissions;
-  private static final int CONFIRMATION_REMOVE_DIALOG = 1;
-
-  // We declare the permissions globally to simplify the code
-  private final PermissionType LOCAL_STORAGE =
-      new PermissionType(LOCAL_STORAGE_STRING);
-  private final PermissionType LOCATION_DATA =
-      new PermissionType(LOCATION_DATA_STRING);
-
-  private boolean mChanges = false;
-
-  SettingsAdapter mListAdapter;
-
-  public GearsSettingsDialog(Activity activity,
-                             Handler handler,
-                             String arguments) {
-    super (activity, handler, arguments);
-    activity.setContentView(R.layout.gears_settings);
-  }
-
-  public void setup() {
-    // First let's add the permissions' resources
-    LOCAL_STORAGE.setResources(R.string.settings_storage_title,
-                               R.string.settings_storage_subtitle_on,
-                               R.string.settings_storage_subtitle_off);
-    LOCATION_DATA.setResources(R.string.settings_location_title,
-                               R.string.settings_location_subtitle_on,
-                               R.string.settings_location_subtitle_off);
-    // add the permissions to the list of permissions.
-    mPermissions = new Vector<PermissionType>();
-    mPermissions.add(LOCAL_STORAGE);
-    mPermissions.add(LOCATION_DATA);
-    OriginPermissions.setListener(this);
-
-
-    setupDialog();
-
-    // We manage the permissions using three vectors, mSitesPermissions,
-    // mOriginalPermissions and mCurrentPermissions.
-    // The dialog's arguments are parsed and a list of permissions is
-    // generated and stored in those three vectors.
-    // mOriginalPermissions is a separate copy and will not be modified;
-    // mSitesPermissions contains the current permissions _only_ --
-    // if an origin is removed, it is also removed from mSitesPermissions.
-    // Finally, mCurrentPermissions contains the current permissions and
-    // is a clone of mSitesPermissions, but removed sites aren't removed,
-    // their permissions are simply set to PERMISSION_NOT_SET. This
-    // allows us to easily generate the final difference between the
-    // original permissions and the final permissions, while directly
-    // using mSitesPermissions for the listView adapter (SettingsAdapter).
-
-    mSitesPermissions = new Vector<OriginPermissions>();
-    mOriginalPermissions = new Vector<OriginPermissions>();
-
-    try {
-      JSONObject json = new JSONObject(mDialogArguments);
-      if (json.has("permissions")) {
-        JSONArray jsonArray = json.getJSONArray("permissions");
-        for (int i = 0; i < jsonArray.length(); i++) {
-          JSONObject infos = jsonArray.getJSONObject(i);
-          String name = null;
-          int localStorage = PermissionType.PERMISSION_NOT_SET;
-          int locationData = PermissionType.PERMISSION_NOT_SET;
-          if (infos.has("name")) {
-            name = infos.getString("name");
-          }
-          if (infos.has(LOCAL_STORAGE_STRING)) {
-            JSONObject perm = infos.getJSONObject(LOCAL_STORAGE_STRING);
-            if (perm.has("permissionState")) {
-              localStorage = perm.getInt("permissionState");
-            }
-          }
-          if (infos.has(LOCATION_DATA_STRING)) {
-            JSONObject perm = infos.getJSONObject(LOCATION_DATA_STRING);
-            if (perm.has("permissionState")) {
-              locationData = perm.getInt("permissionState");
-            }
-          }
-          OriginPermissions perms = new OriginPermissions(name);
-          perms.setPermission(LOCAL_STORAGE, localStorage);
-          perms.setPermission(LOCATION_DATA, locationData);
-
-          mSitesPermissions.add(perms);
-          mOriginalPermissions.add(new OriginPermissions(perms));
-        }
-      }
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception ", e);
-    }
-    mCurrentPermissions = (Vector<OriginPermissions>)mSitesPermissions.clone();
-
-    View listView = findViewById(R.id.sites_list);
-    if (listView != null) {
-      ListView list = (ListView) listView;
-      mListAdapter = new SettingsAdapter(mActivity, mSitesPermissions);
-      list.setAdapter(mListAdapter);
-      list.setScrollBarStyle(android.view.View.SCROLLBARS_OUTSIDE_INSET);
-      list.setOnItemClickListener(mListAdapter);
-    }
-    if (mDebug) {
-      printPermissions();
-    }
-  }
-
-  private void setMainTitle() {
-    String windowTitle = mActivity.getString(R.string.pref_extras_gears_settings);
-    mActivity.setTitle(windowTitle);
-  }
-
-  public void setupDialog() {
-    setMainTitle();
-  }
-
-  /**
-   * GearsPermissions.PermissionsChangesListener delegate
-   */
-  public boolean setPermission(PermissionType type, int perm) {
-    if (mChanges == false) {
-      mChanges = true;
-    }
-    return mChanges;
-  }
-
-  public boolean handleBackButton() {
-    return mListAdapter.backButtonPressed();
-  }
-
-  /**
-   * We use this to create a confirmation dialog when the user
-   * clicks on "remove this site from gears"
-   */
-  public Dialog onCreateDialog(int id) {
-    return new AlertDialog.Builder(mActivity)
-        .setTitle(R.string.settings_confirmation_remove_title)
-        .setMessage(R.string.settings_confirmation_remove)
-        .setPositiveButton(android.R.string.ok,
-                           new AlertDialog.OnClickListener() {
-          public void onClick(DialogInterface dlg, int which) {
-            mListAdapter.removeCurrentSite();
-          }
-        })
-        .setNegativeButton(android.R.string.cancel, null)
-        .setIcon(android.R.drawable.ic_dialog_alert)
-        .create();
-  }
-
-  /**
-   * Adapter class for the list view in the settings dialog
-   *
-   * We first display a list of all the origins (sites), or
-   * a message saying that no permission is set if the list is empty.
-   * When the user click on one of the origin, we then display
-   * the list of the permissions existing for that origin.
-   * Each permission can be either allowed or denied by clicking
-   * on the checkbox.
-   * The last row is a special case, allowing to remove the entire origin.
-   */
-  class SettingsAdapter extends BaseAdapter
-      implements AdapterView.OnItemClickListener {
-    private Activity mContext;
-    private List mItems;
-    private OriginPermissions mCurrentSite;
-    private Vector mCurrentPermissions;
-    private int MAX_ROW_HEIGHT = 64;
-
-    SettingsAdapter(Activity context, List items) {
-      mContext = context;
-      mItems = items;
-      mCurrentSite = null;
-    }
-
-    public int getCount() {
-      if (mCurrentSite == null) {
-        int size = mItems.size();
-        if (size == 0) {
-          return 1;
-        } else {
-          return size;
-        }
-      }
-      return mCurrentPermissions.size() + 1;
-    }
-
-    public long getItemId(int position) {
-      return position;
-    }
-
-    private String shortName(String url) {
-        // We remove the http and https prefix
-        if (url.startsWith("http://")) {
-          return url.substring(7);
-        }
-        if (url.startsWith("https://")) {
-          return url.substring(8);
-        }
-        return url;
-    }
-
-    public Object getItem(int position) {
-      if (mCurrentSite == null) {
-        if (mItems.size() == 0) {
-          return null;
-        } else {
-          return mItems.get(position);
-        }
-      }
-      return mCurrentPermissions.get(position);
-    }
-
-    public View getView(int position, View convertView, ViewGroup parent) {
-      View row = convertView;
-      if (row == null) { // no cached view, we create one
-        LayoutInflater inflater = (LayoutInflater) getSystemService(
-            Context.LAYOUT_INFLATER_SERVICE);
-        row = inflater.inflate(R.layout.gears_settings_row, null);
-      }
-      row.setMinimumHeight(MAX_ROW_HEIGHT);
-
-      if (mCurrentSite == null) {
-        if (mItems.size() == 0) {
-          hideView(row, R.id.title);
-          hideView(row, R.id.subtitle);
-          hideView(row, R.id.checkbox);
-          hideView(row, R.id.icon);
-          setText(row, R.id.info, R.string.settings_empty);
-        } else {
-          hideView(row, R.id.subtitle);
-          hideView(row, R.id.info);
-          hideView(row, R.id.checkbox);
-          OriginPermissions perms = (OriginPermissions) mItems.get(position);
-          setText(row, R.id.title, shortName(perms.getOrigin()));
-          showView(row, R.id.icon);
-        }
-      } else {
-        if (position == getCount() - 1) {
-          // last position: "remove this site from gears"
-          hideView(row, R.id.subtitle);
-          hideView(row, R.id.info);
-          hideView(row, R.id.checkbox);
-          hideView(row, R.id.icon);
-          setText(row, R.id.title, R.string.settings_remove_site);
-        } else {
-          hideView(row, R.id.info);
-          hideView(row, R.id.icon);
-          showView(row, R.id.checkbox);
-
-          PermissionType type =
-              (PermissionType) mCurrentPermissions.get(position);
-          setText(row, R.id.title, type.getTitleRsc());
-
-          View checkboxView = row.findViewById(R.id.checkbox);
-          if (checkboxView != null) {
-            CheckBox checkbox = (CheckBox) checkboxView;
-            int perm = mCurrentSite.getPermission(type);
-            if (perm == PermissionType.PERMISSION_DENIED) {
-              setText(row, R.id.subtitle, type.getSubtitleOffRsc());
-              checkbox.setChecked(false);
-            } else {
-              setText(row, R.id.subtitle, type.getSubtitleOnRsc());
-              checkbox.setChecked(true);
-            }
-          }
-        }
-      }
-      return row;
-    }
-
-    public void removeCurrentSite() {
-      mCurrentSite.setPermission(LOCAL_STORAGE,
-                                 PermissionType.PERMISSION_NOT_SET);
-      mCurrentSite.setPermission(LOCATION_DATA,
-                                 PermissionType.PERMISSION_NOT_SET);
-      mSitesPermissions.remove(mCurrentSite);
-      mCurrentSite = null;
-      setMainTitle();
-      notifyDataSetChanged();
-    }
-
-    public void onItemClick(AdapterView<?> parent,
-                            View view,
-                            int position,
-                            long id) {
-      if (mItems.size() == 0) {
-        return;
-      }
-      if (mCurrentSite == null) {
-         mCurrentSite = (OriginPermissions) mItems.get(position);
-         mCurrentPermissions = new Vector();
-         for (int i = 0; i < mPermissions.size(); i++) {
-           PermissionType type = mPermissions.get(i);
-           int perm = mCurrentSite.getPermission(type);
-           if (perm != PermissionType.PERMISSION_NOT_SET) {
-             mCurrentPermissions.add(type);
-           }
-         }
-         mContext.setTitle(shortName(mCurrentSite.getOrigin()));
-      } else {
-        if (position == getCount() - 1) { // last item (remove site)
-          // Ask the user to confirm
-          // If yes, removeCurrentSite() will be called via the dialog callback.
-          mActivity.showDialog(CONFIRMATION_REMOVE_DIALOG);
-        } else {
-          PermissionType type =
-              (PermissionType) mCurrentPermissions.get(position);
-          if (mCurrentSite.getPermission(type) ==
-              PermissionType.PERMISSION_ALLOWED) {
-            mCurrentSite.setPermission(type, PermissionType.PERMISSION_DENIED);
-          } else {
-            mCurrentSite.setPermission(type, PermissionType.PERMISSION_ALLOWED);
-          }
-        }
-      }
-      notifyDataSetChanged();
-    }
-
-    public boolean backButtonPressed() {
-      if (mCurrentSite != null) { // we intercept the back button
-        mCurrentSite = null;
-        setMainTitle();
-        notifyDataSetChanged();
-        return true;
-      }
-      return false;
-    }
-
-  }
-
-  /**
-   * Utility method used in debug mode to print the list of
-   * permissions (original values and current values).
-   */
-  public void printPermissions() {
-    Log.v(TAG, "Original Permissions: ");
-    for (int i = 0; i < mOriginalPermissions.size(); i++) {
-      OriginPermissions p = mOriginalPermissions.get(i);
-      p.print();
-    }
-    Log.v(TAG, "Current Permissions: ");
-    for (int i = 0; i < mSitesPermissions.size(); i++) {
-      OriginPermissions p = mSitesPermissions.get(i);
-      p.print();
-    }
-  }
-
-  /**
-   * Computes the difference between the original permissions and the
-   * current ones. Returns a json-formatted string.
-   * It is used by the Settings dialog.
-   */
-  public String computeDiff(boolean modif) {
-    String ret = null;
-    try {
-      JSONObject results = new JSONObject();
-      JSONArray permissions = new JSONArray();
-
-      for (int i = 0; modif && i < mOriginalPermissions.size(); i++) {
-        OriginPermissions original = mOriginalPermissions.get(i);
-        OriginPermissions current = mCurrentPermissions.get(i);
-        JSONObject permission = new JSONObject();
-        boolean modifications = false;
-
-        for (int j = 0; j < mPermissions.size(); j++) {
-          PermissionType type = mPermissions.get(j);
-
-          if (current.getPermission(type) != original.getPermission(type)) {
-            JSONObject state = new JSONObject();
-            state.put("permissionState", current.getPermission(type));
-            permission.put(type.getName(), state);
-            modifications = true;
-          }
-        }
-
-        if (modifications) {
-          permission.put("name", current.getOrigin());
-          permissions.put(permission);
-        }
-      }
-      results.put("modifiedOrigins", permissions);
-      ret = results.toString();
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception ", e);
-    }
-    return ret;
-  }
-
-  public String closeDialog(int closingType) {
-    String ret = computeDiff(mChanges);
-
-    if (mDebug) {
-      printPermissions();
-    }
-
-    return ret;
-  }
-
-}
