diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index 23c0fac..cf3fe70 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -119,16 +119,13 @@
         boolean emptyTitle = title.length() == 0;
         boolean emptyUrl = unfilteredUrl.trim().length() == 0;
         Resources r = getResources();
-        if (emptyTitle) {
+        if (emptyTitle || emptyUrl) {
+            if (emptyTitle) {
+                mTitle.setError(r.getText(R.string.bookmark_needs_title));
+            }
             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));
+                mAddress.setError(r.getText(R.string.bookmark_needs_url));
+            }
             return false;
         }
         String url = unfilteredUrl;
@@ -138,11 +135,11 @@
             try {
                 address = new WebAddress(unfilteredUrl);
             } catch (ParseException e) {
-                setTitle(r.getText(R.string.bookmark_url_not_valid));
+                mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
                 return false;
             }
             if (address.mHost.length() == 0) {
-                setTitle(r.getText(R.string.bookmark_url_not_valid));
+                mAddress.setError(r.getText(R.string.bookmark_url_not_valid));
                 return false;
             }
             url = address.toString();
diff --git a/src/com/android/browser/BrowserActivity.java b/src/com/android/browser/BrowserActivity.java
index 0ca4248..6179da2 100644
--- a/src/com/android/browser/BrowserActivity.java
+++ b/src/com/android/browser/BrowserActivity.java
@@ -1950,15 +1950,17 @@
                             public void run() {
                                 // Remove the AnimatingView.
                                 mContentView.removeView(view);
-                                // 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 (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) {
@@ -1976,10 +1978,12 @@
                                     if (currentTab != tab) {
                                         mTabControl.setCurrentTab(currentTab);
                                     }
-                                    mTabOverview.remove(newIndex);
-                                    // Make the current tab visible.
-                                    mTabOverview.setCurrentIndex(
-                                            mTabControl.getCurrentIndex());
+                                    if (mTabOverview != null) {
+                                        mTabOverview.remove(newIndex);
+                                        // Make the current tab visible.
+                                        mTabOverview.setCurrentIndex(
+                                                mTabControl.getCurrentIndex());
+                                    }
                                 }
                             }
                         });
diff --git a/src/com/android/browser/BrowserHistoryPage.java b/src/com/android/browser/BrowserHistoryPage.java
index c529fe8..42ca848 100644
--- a/src/com/android/browser/BrowserHistoryPage.java
+++ b/src/com/android/browser/BrowserHistoryPage.java
@@ -115,11 +115,18 @@
         addContentView(v, new LayoutParams(LayoutParams.FILL_PARENT,
                 LayoutParams.FILL_PARENT));
         list.setEmptyView(v);
-        list.post(new Runnable() {
-            public void run() {
-                list.expandGroup(0);
-            }
-        });
+        // Do not post the runnable if there is nothing in the list.
+        if (list.getExpandableListAdapter().getGroupCount() > 0) {
+            list.post(new Runnable() {
+                public void run() {
+                    // In case the history gets cleared before this event
+                    // happens.
+                    if (list.getExpandableListAdapter().getGroupCount() > 0) {
+                        list.expandGroup(0);
+                    }
+                }
+            });
+        }
         mMaxTabsOpen = getIntent().getBooleanExtra("maxTabsOpen", false);
         CombinedBookmarkHistoryActivity.getIconListenerSet(getContentResolver())
                 .addListener(mIconReceiver);
@@ -258,9 +265,12 @@
     
     private class HistoryAdapter implements ExpandableListAdapter {
         
-        // Map of items. Negative values are labels, positive values
-        // and zero are cursor offsets.
+        // Array for each of our bins.  Each entry represents how many items are
+        // in that bin.
         int mItemMap[];
+        // This is our GroupCount.  We will have at most DateSorter.DAY_COUNT
+        // bins, less if the user has no items in one or more bins.
+        int mNumberOfBins;
         Vector<DataSetObserver> mObservers;
         Cursor mCursor;
         
@@ -295,12 +305,14 @@
             for (int j = 0; j < DateSorter.DAY_COUNT; j++) {
                 array[j] = 0;
             }
+            mNumberOfBins = 0;
             int dateIndex = -1;
             if (mCursor.moveToFirst() && mCursor.getCount() > 0) {
                 while (!mCursor.isAfterLast()) {
                     long date = mCursor.getLong(Browser.HISTORY_PROJECTION_DATE_INDEX);
                     int index = mDateSorter.getIndex(date);
                     if (index > dateIndex) {
+                        mNumberOfBins++;
                         if (index == DateSorter.DAY_COUNT - 1) {
                             // We are already in the last bin, so it will
                             // include all the remaining items
@@ -316,9 +328,37 @@
             }
             mItemMap = array;
         }
-        
+
+        // This translates from a group position in the Adapter to a position in
+        // our array.  This is necessary because some positions in the array
+        // have no history items, so we simply do not present those positions
+        // to the Adapter.
+        private int groupPositionToArrayPosition(int groupPosition) {
+            if (groupPosition < 0 || groupPosition >= DateSorter.DAY_COUNT) {
+                throw new AssertionError("group position out of range");
+            }
+            if (DateSorter.DAY_COUNT == mNumberOfBins || 0 == mNumberOfBins) {
+                // In the first case, we have exactly the same number of bins
+                // as our maximum possible, so there is no need to do a
+                // conversion
+                // The second statement is in case this method gets called when
+                // the array is empty, in which case the provided groupPosition
+                // will do fine.
+                return groupPosition;
+            }
+            int arrayPosition = -1;
+            while (groupPosition > -1) {
+                arrayPosition++;
+                if (mItemMap[arrayPosition] != 0) {
+                    groupPosition--;
+                }
+            }
+            return arrayPosition;
+        }
+
         public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
                 View convertView, ViewGroup parent) {
+            groupPosition = groupPositionToArrayPosition(groupPosition);
             HistoryItem item;
             if (null == convertView || !(convertView instanceof HistoryItem)) {
                 item = new HistoryItem(BrowserHistoryPage.this);
@@ -347,6 +387,7 @@
         }
         
         public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) {
+            groupPosition = groupPositionToArrayPosition(groupPosition);
             TextView item;
             if (null == convertView || !(convertView instanceof TextView)) {
                 LayoutInflater factory = 
@@ -369,11 +410,11 @@
         }
 
         public int getGroupCount() {
-            return DateSorter.DAY_COUNT;
+            return mNumberOfBins;
         }
 
         public int getChildrenCount(int groupPosition) {
-            return mItemMap[groupPosition];
+            return mItemMap[groupPositionToArrayPosition(groupPosition)];
         }
 
         public Object getGroup(int groupPosition) {
diff --git a/src/com/android/browser/BrowserHomepagePreference.java b/src/com/android/browser/BrowserHomepagePreference.java
index bc21143..d4708c3 100644
--- a/src/com/android/browser/BrowserHomepagePreference.java
+++ b/src/com/android/browser/BrowserHomepagePreference.java
@@ -48,8 +48,10 @@
         AlertDialog dialog = (AlertDialog) getDialog();
         // This callback is called before the dialog has been fully constructed
         if (dialog != null) {
+            String url = s.toString();
             dialog.getButton(DialogInterface.BUTTON_POSITIVE).setEnabled(
-                    Regex.WEB_URL_PATTERN.matcher(s.toString()).matches());
+                    url.length() == 0 || url.equals("about:blank") ||
+                    Regex.WEB_URL_PATTERN.matcher(url).matches());
         }
     }
 
diff --git a/src/com/android/browser/BrowserPreferencesPage.java b/src/com/android/browser/BrowserPreferencesPage.java
index b23f750..5d6795b 100644
--- a/src/com/android/browser/BrowserPreferencesPage.java
+++ b/src/com/android/browser/BrowserPreferencesPage.java
@@ -83,8 +83,7 @@
             if (needUpdate) {
                 value = value.trim().replace(" ", "%20");
             }
-            Uri path = Uri.parse(value);
-            if (path.getScheme() == null) {
+            if (value.length() != 0 && Uri.parse(value).getScheme() == null) {
                 value = "http://" + value;
                 needUpdate = true;
             }
diff --git a/src/com/android/browser/FindDialog.java b/src/com/android/browser/FindDialog.java
index 44109ff..43cd1c4 100644
--- a/src/com/android/browser/FindDialog.java
+++ b/src/com/android/browser/FindDialog.java
@@ -17,6 +17,7 @@
 package com.android.browser;
 
 import android.app.Dialog;
+import android.content.Context;
 import android.content.res.Configuration;
 import android.os.Bundle;
 import android.os.Handler;
@@ -30,6 +31,7 @@
 import android.view.ViewGroup;
 import android.view.Window;
 import android.view.WindowManager;
+import android.view.inputmethod.InputMethodManager;
 import android.webkit.WebView;
 import android.widget.EditText;
 import android.widget.TextView;
@@ -66,9 +68,19 @@
                 throw new AssertionError("No WebView for FindDialog::onClick");
             }
             mWebView.findNext(false);
+            hideSoftInput();
         }
     };
-    
+
+    /*
+     * Remove the soft keyboard from the screen.
+     */
+    private void hideSoftInput() {
+        InputMethodManager imm = (InputMethodManager)
+                mBrowserActivity.getSystemService(Context.INPUT_METHOD_SERVICE);
+        imm.hideSoftInputFromWindow(mEditText.getWindowToken(), 0);
+    }
+
     private void disableButtons() {
         mPrevButton.setEnabled(false);
         mNextButton.setEnabled(false);
@@ -157,8 +169,9 @@
             throw new AssertionError("No WebView for FindDialog::findNext");
         }
         mWebView.findNext(true);
+        hideSoftInput();
     }
-    
+
     public void show() {
         super.show();
         mEditText.requestFocus();
diff --git a/src/com/android/browser/GearsFilePickerDialog.java b/src/com/android/browser/GearsFilePickerDialog.java
deleted file mode 100644
index 10cc03f..0000000
--- a/src/com/android/browser/GearsFilePickerDialog.java
+++ /dev/null
@@ -1,930 +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.content.Context;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.BitmapFactory;
-import android.graphics.Color;
-import android.net.Uri;
-import android.os.Environment;
-import android.os.Handler;
-import android.os.Looper;
-import android.os.Message;
-import android.provider.MediaStore;
-import android.provider.MediaStore.Images.Media;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.MotionEvent;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.AdapterView;
-import android.widget.BaseAdapter;
-import android.widget.GridView;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Vector;
-
-import org.json.JSONArray;
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears FilePicker dialog
- */
-class GearsFilePickerDialog extends GearsBaseDialog
-  implements View.OnTouchListener {
-
-  private static final String TAG = "Gears FilePicker";
-  private static Bitmap mDirectoryIcon;
-  private static Bitmap mDefaultIcon;
-  private static Bitmap mImageIcon;
-  private static Bitmap mBackIcon;
-
-  private static String MULTIPLE_FILES = "MULTIPLE_FILES";
-  private static String SINGLE_FILE = "SINGLE_FILE";
-
-  private static ImagesLoad mImagesLoader;
-  private static SystemThumbnails mSystemThumbnails;
-  private FilePickerAdapter mAdapter;
-  private String mSelectionMode;
-  private boolean mMultipleSelection;
-  private String mCurrentPath;
-
-  // Disable saving thumbnails until this is refactored to fit into
-  // existing schemes.
-  private static final boolean enableSavedThumbnails = false;
-
-  public GearsFilePickerDialog(Activity activity,
-                               Handler handler,
-                               String arguments) {
-    super (activity, handler, arguments);
-    mAdapter = new FilePickerAdapter(activity);
-    parseArguments();
-  }
-
-  public void parseArguments() {
-    mSelectionMode = MULTIPLE_FILES;
-    try {
-      JSONObject json = new JSONObject(mDialogArguments);
-
-      if (json.has("mode")) {
-        mSelectionMode = json.getString("mode");
-      }
-    } catch (JSONException e) {
-      Log.e(TAG, "exc: " + e);
-    }
-    if (mSelectionMode.equalsIgnoreCase(SINGLE_FILE)) {
-      mMultipleSelection = false;
-    } else {
-      mMultipleSelection = true;
-    }
-  }
-
-  public void setup() {
-    inflate(R.layout.gears_dialog_filepicker, R.id.panel_content);
-    setupButtons(0,
-                 R.string.filepicker_button_allow,
-                 R.string.filepicker_button_deny);
-    setupDialog();
-
-    TextView textViewPath = (TextView) findViewById(R.id.path_name);
-    if (textViewPath != null) {
-      textViewPath.setText(R.string.filepicker_path);
-    }
-
-    GridView view = (GridView) findViewById(R.id.files_list);
-    view.setAdapter(mAdapter);
-    view.setOnTouchListener(this);
-
-    showView(null, R.id.selection);
-    setSelectionText();
-
-    mImagesLoader = new ImagesLoad(mAdapter);
-    mImagesLoader.setAdapterView(view);
-    Thread imagesLoaderThread = new Thread(mImagesLoader);
-    imagesLoaderThread.setPriority(Thread.MIN_PRIORITY);
-    imagesLoaderThread.start();
-
-    mSystemThumbnails = new SystemThumbnails();
-    Thread systemThumbnailsThread = new Thread(mSystemThumbnails);
-    systemThumbnailsThread.setPriority(Thread.MIN_PRIORITY);
-    systemThumbnailsThread.start();
-  }
-
-  public void setSelectionText() {
-    Vector elements = mAdapter.selectedElements();
-    if (elements == null)
-      return;
-    TextView info = (TextView) findViewById(R.id.selection);
-    int nbElements = elements.size();
-    if (nbElements == 0) {
-      info.setText(R.string.filepicker_no_files_selected);
-    } else if (nbElements == 1) {
-      info.setText(R.string.filepicker_one_file_selected);
-    } else {
-      info.setText(nbElements + " " +
-                   mActivity.getString(
-                       R.string.filepicker_some_files_selected));
-    }
-  }
-
-  public void setCurrentPath(String path) {
-    if (path != null) {
-      mCurrentPath = path;
-      TextView textViewPath = (TextView) findViewById(R.id.current_path);
-      if (textViewPath != null) {
-        textViewPath.setText(path);
-      }
-    }
-  }
-
-  public void setupDialog(TextView message, ImageView icon) {
-    message.setText(R.string.filepicker_message);
-    message.setTextSize(24);
-    icon.setImageResource(R.drawable.ic_dialog_menu_generic);
-  }
-
-  public boolean onTouch(View v, MotionEvent event) {
-    mImagesLoader.pauseIconRequest();
-    return false;
-  }
-
-  /**
-   * Utility class encapsulating thumbnails information
-   * for a file (file image id and magic number)
-   */
-  class SystemThumbnailInfo {
-    private long mID;
-    private long mMagicNumber;
-    SystemThumbnailInfo(long anID, long magicNumber) {
-      mID = anID;
-      mMagicNumber = magicNumber;
-    }
-    public long getID() {
-      return mID;
-    }
-    public long getMagicNumber() {
-      return mMagicNumber;
-    }
-  }
-
-  /**
-   * Utility class to pre-fetch the thumbnails information
-   */
-  class SystemThumbnails implements Runnable {
-    private Map<String, SystemThumbnailInfo> mThumbnails;
-
-    SystemThumbnails() {
-      mThumbnails = Collections.synchronizedMap(new HashMap());
-    }
-
-    public void run() {
-      Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-      Cursor cursor = mActivity.managedQuery(query,
-          new String[] { "_id", "mini_thumb_magic", "_data" },
-          null, null, null);
-
-      if (cursor != null) {
-        int count = cursor.getCount();
-        for (int i = 0; i < count; i++) {
-          cursor.moveToPosition(i);
-          SystemThumbnailInfo info = new SystemThumbnailInfo(cursor.getLong(0),
-                                                             cursor.getLong(1));
-          mThumbnails.put(cursor.getString(2), info);
-        }
-      }
-    }
-
-    public SystemThumbnailInfo getThumb(String path) {
-      SystemThumbnailInfo ret = mThumbnails.get(path);
-      if (ret == null) {
-        Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-        Cursor cursor = mActivity.managedQuery(query,
-          new String[] { "_id", "mini_thumb_magic", "_data" },
-              "_data = ?", new String[] { path }, null);
-        if (cursor != null && cursor.moveToFirst()) {
-          long longid = cursor.getLong(0);
-          long miniThumbMagic = cursor.getLong(1);
-          ret = new SystemThumbnailInfo(longid, miniThumbMagic);
-          mThumbnails.put(path, ret);
-        }
-      }
-      return ret;
-    }
-  }
-
-  /**
-   * Utility class to load and generate thumbnails
-   * for image files
-   */
-  class ImagesLoad implements Runnable {
-    private Vector mImagesPath;
-    private BaseAdapter mAdapter;
-    private AdapterView mAdapterView;
-    private Vector<FilePickerElement> mElements;
-    private Handler mLoaderHandler;
-    // We use the same value as in Camera.app's ImageManager.java
-    private static final int BYTES_PER_MINI_THUMB = 10000;
-    private final byte[] mMiniThumbData = new byte[BYTES_PER_MINI_THUMB];
-    private final int MINI_THUMB_DATA_FILE_VERSION = 3;
-    private final int THUMBNAIL_SIZE = 128;
-    private Map<Uri, RandomAccessFile> mThumbFiles;
-
-    ImagesLoad(BaseAdapter adapter) {
-      mAdapter = adapter;
-      mThumbFiles = Collections.synchronizedMap(new HashMap());
-    }
-
-    public void signalChanges() {
-      Message message = mHandler.obtainMessage(GearsBaseDialog.NEW_ICON,
-                                               mAdapter);
-      mHandler.sendMessage(message);
-    }
-
-    private String getMiniThumbFileFromUri(Uri uri) {
-      if (uri == null) {
-        return null;
-      }
-      String directoryName =
-          Environment.getExternalStorageDirectory().toString() +
-          "/dcim/.thumbnails";
-      String path = directoryName + "/.thumbdata" +
-          MINI_THUMB_DATA_FILE_VERSION + "-" + uri.hashCode();
-      return path;
-    }
-
-    private Bitmap getMiniThumbFor(Uri uri, long longid, long magic) {
-      RandomAccessFile thumbFile = mThumbFiles.get(uri);
-      try {
-        if (thumbFile == null) {
-          String path = getMiniThumbFileFromUri(uri);
-          File f = new File(path);
-          if (f.exists()) {
-            thumbFile = new RandomAccessFile(f, "rw");
-            mThumbFiles.put(uri, thumbFile);
-          }
-        }
-      } catch (IOException ex) {
-      }
-      if (thumbFile == null) {
-        return null;
-      }
-      byte[] data = getMiniThumbFromFile(thumbFile, longid,
-                                         mMiniThumbData, magic);
-      if (data != null) {
-        return BitmapFactory.decodeByteArray(data, 0, data.length);
-      }
-      return null;
-    }
-
-    private byte [] getMiniThumbFromFile(RandomAccessFile r,
-                                         long id,
-                                         byte [] data,
-                                         long magicCheck) {
-      if (r == null)
-        return null;
-      long pos = id * BYTES_PER_MINI_THUMB;
-      RandomAccessFile f = r;
-      synchronized (f) {
-        try {
-          f.seek(pos);
-          if (f.readByte() == 1) {
-            long magic = f.readLong();
-            if (magic != magicCheck) {
-              return null;
-            }
-            int length = f.readInt();
-            f.read(data, 0, length);
-            return data;
-          } else {
-            return null;
-          }
-        } catch (IOException ex) {
-          long fileLength;
-          try {
-            fileLength = f.length();
-          } catch (IOException ex1) {
-            fileLength = -1;
-          }
-          return null;
-        }
-      }
-    }
-
-    /*
-     * Returns a thumbnail saved by the Camera application
-     * We pre-cached the information (image id and magic number)
-     * when starting the filepicker.
-     */
-    public Bitmap getSystemThumbnail(FilePickerElement elem) {
-      if (elem.askedForSystemThumbnail() == false) {
-        elem.setAskedForSystemThumbnail(true);
-        String path = elem.getPath();
-        SystemThumbnailInfo thumbInfo = mSystemThumbnails.getThumb(path);
-        if (thumbInfo != null) {
-          Uri query = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
-          Bitmap bmp = getMiniThumbFor(query, thumbInfo.getID(),
-                                       thumbInfo.getMagicNumber());
-          if (bmp != null) {
-            return bmp;
-          }
-        }
-      }
-      return null;
-    }
-
-    /*
-     * Generate a thumbnail for a given element
-     */
-    public Bitmap generateImage(FilePickerElement elem) {
-      String path = elem.getPath();
-      Bitmap finalImage = null;
-      try {
-
-        // First we try to get the thumbnail from the system
-        // (created by the Camera application)
-
-        finalImage = getSystemThumbnail(elem);
-        if (finalImage != null) {
-          return finalImage;
-        }
-
-        // No thumbnail was found, so we have to create one
-        //
-        // First we get the image information and
-        // determine the sampleSize
-
-        BitmapFactory.Options options = new BitmapFactory.Options();
-        options.inJustDecodeBounds = true;
-        BitmapFactory.decodeFile(path, options);
-
-        int width = options.outWidth;
-        int height = options.outHeight;
-        int sampleSize = 1;
-        if (width > THUMBNAIL_SIZE || height > THUMBNAIL_SIZE) {
-          sampleSize = 2;
-          while ((width / sampleSize > 2*THUMBNAIL_SIZE)
-                 || (height / sampleSize > 2*THUMBNAIL_SIZE)) {
-            sampleSize += 2;
-          }
-        }
-        options.inJustDecodeBounds = false;
-        options.inSampleSize = sampleSize;
-        Bitmap originalImage = BitmapFactory.decodeFile(path, options);
-        if (originalImage == null) {
-          return null;
-        }
-
-        // Let's rescale the image to a THUMBNAIL_SIZE
-
-        width = originalImage.getWidth();
-        height = originalImage.getHeight();
-
-        if (width > height) {
-          width = (int) (width * (THUMBNAIL_SIZE / (double) height));
-          height = THUMBNAIL_SIZE;
-        } else {
-          height = (int) (height * (THUMBNAIL_SIZE / (double) width));
-          width = THUMBNAIL_SIZE;
-        }
-        originalImage = Bitmap.createScaledBitmap(originalImage,
-                                                  width, height, true);
-
-        // We can now crop the image to a THUMBNAIL_SIZE rectangle
-
-        width = originalImage.getWidth();
-        height = originalImage.getHeight();
-        int d = 0;
-        if (width > height) {
-          d = (width - height) / 2;
-          finalImage = Bitmap.createBitmap(originalImage, d, 0,
-                                           THUMBNAIL_SIZE, THUMBNAIL_SIZE);
-        } else {
-          d = (height - width) / 2;
-          finalImage = Bitmap.createBitmap(originalImage, 0, d,
-                                           THUMBNAIL_SIZE, THUMBNAIL_SIZE);
-        }
-
-        originalImage.recycle();
-      } catch (java.lang.OutOfMemoryError e) {
-        Log.e(TAG, "Intercepted OOM ", e);
-      }
-      return finalImage;
-    }
-
-    public void pauseIconRequest() {
-      Message message = Message.obtain(mLoaderHandler,
-                                       GearsBaseDialog.PAUSE_REQUEST_ICON);
-      mLoaderHandler.sendMessageAtFrontOfQueue(message);
-    }
-
-    public void clearIconRequests() {
-      Message message = Message.obtain(mLoaderHandler,
-                                       GearsBaseDialog.CLEAR_REQUEST_ICON);
-      mLoaderHandler.sendMessageAtFrontOfQueue(message);
-    }
-
-    public void postIconRequest(FilePickerElement item,
-                                int position,
-                                boolean front) {
-      if (item == null) {
-        return;
-      }
-      if (item.isImage() && (item.getThumbnail() == null))  {
-        Message message = mLoaderHandler.obtainMessage(
-            GearsBaseDialog.REQUEST_ICON, position, 0, item);
-        if (front) {
-          mLoaderHandler.sendMessageAtFrontOfQueue(message);
-        } else {
-          mLoaderHandler.sendMessage(message);
-        }
-      }
-    }
-
-    public boolean generateIcon(FilePickerElement elem) {
-      if (elem.isImage()) {
-        if (elem.getThumbnail() == null) {
-          Bitmap image = generateImage(elem);
-          if (image != null) {
-            elem.setThumbnail(image);
-            return true;
-          }
-        }
-      }
-      return false;
-    }
-
-    public void setAdapterView(AdapterView view) {
-      mAdapterView = view;
-    }
-
-    public void run() {
-      Looper.prepare();
-      mLoaderHandler = new Handler() {
-        public void handleMessage(Message msg) {
-          if (msg.what == GearsBaseDialog.CLEAR_REQUEST_ICON) {
-            mLoaderHandler.removeMessages(
-                GearsBaseDialog.PAUSE_REQUEST_ICON);
-            mLoaderHandler.removeMessages(
-                GearsBaseDialog.REQUEST_ICON);
-          } else if (msg.what == GearsBaseDialog.PAUSE_REQUEST_ICON) {
-            try {
-              // We are busy (likely) scrolling the view,
-              // so we just pause the loading.
-              Thread.sleep(1000);
-              mLoaderHandler.removeMessages(
-                  GearsBaseDialog.PAUSE_REQUEST_ICON);
-            } catch (InterruptedException e) {
-              Log.e(TAG, "InterruptedException ", e);
-            }
-          } else if (msg.what == GearsBaseDialog.REQUEST_ICON) {
-            FilePickerElement elem = (FilePickerElement) msg.obj;
-            if (generateIcon(elem)) {
-              signalChanges();
-            }
-            try {
-              Thread.sleep(50);
-            } catch (InterruptedException e) {
-              Log.e(TAG, "InterruptedException ", e);
-            }
-          }
-        }
-      };
-      Looper.loop();
-    }
-  }
-
-  /**
-   * Utility class representing an element displayed in the
-   * file picker, associated with an icon and/or thumbnail
-   */
-  class FilePickerElement {
-    private File mPath;
-    private String mName;
-    private Bitmap mIcon;
-    private boolean mIsSelected;
-    private Vector mChildren;
-    private FilePickerElement mParent;
-    private boolean mIsParent;
-    private BaseAdapter mAdapter;
-    private String mExtension;
-    private Bitmap mThumbnail;
-    private boolean mIsImage;
-    private boolean mAskedForSystemThumbnail;
-
-    public FilePickerElement(String name, BaseAdapter adapter) {
-      this(name, adapter, null);
-    }
-
-    public FilePickerElement(String path, String name, BaseAdapter adapter) {
-      this(path, name, adapter, null);
-    }
-
-    public FilePickerElement(String name,
-                             BaseAdapter adapter,
-                             FilePickerElement parent) {
-      mName = name;
-      mAdapter = adapter;
-      mParent = parent;
-      mIsSelected = false;
-      mChildren = null;
-      mAskedForSystemThumbnail = false;
-    }
-
-    public FilePickerElement(String path,
-                             String name,
-                             BaseAdapter adapter,
-                             FilePickerElement parent) {
-      mPath = new File(path);
-      mName = name;
-      mIsSelected = false;
-      mChildren = null;
-      mParent = parent;
-      mAdapter = adapter;
-      mExtension = null;
-      mAskedForSystemThumbnail = false;
-
-      setIcons();
-    }
-
-    public void setAskedForSystemThumbnail(boolean value) {
-      mAskedForSystemThumbnail = value;
-    }
-
-    public boolean askedForSystemThumbnail() {
-      return mAskedForSystemThumbnail;
-    }
-
-    public void setIcons() {
-      if (mPath.isDirectory()) {
-        if (mDirectoryIcon == null) {
-          mDirectoryIcon = BitmapFactory.decodeResource(
-              getResources(), R.drawable.gears_folder);
-        }
-        mIcon = mDirectoryIcon;
-
-      } else {
-        if (isImage()) {
-          if (mImageIcon == null) {
-            mImageIcon = BitmapFactory.decodeResource(
-                getResources(), R.drawable.gears_file_image);
-          }
-          mIcon = mImageIcon;
-        } else if (isAudio()) {
-          mIcon = BitmapFactory.decodeResource(
-              getResources(), R.drawable.gears_file_audio);
-        } else if (isVideo()) {
-          mIcon = BitmapFactory.decodeResource(
-              getResources(), R.drawable.gears_file_video);
-        } else {
-          if (mDefaultIcon == null) {
-            mDefaultIcon = BitmapFactory.decodeResource(
-                getResources(), R.drawable.gears_file_unknown);
-          }
-          mIcon = mDefaultIcon;
-        }
-      }
-      if (mBackIcon == null) {
-        mBackIcon = BitmapFactory.decodeResource(getResources(),
-                com.android.internal.R.drawable.ic_menu_back);
-      }
-    }
-
-    public boolean isImage() {
-      if (mIsImage) return mIsImage;
-      String extension = getExtension();
-      if (extension != null) {
-        if (extension.equalsIgnoreCase("jpg") ||
-            extension.equalsIgnoreCase("jpeg") ||
-            extension.equalsIgnoreCase("png") ||
-            extension.equalsIgnoreCase("gif")) {
-          mIsImage = true;
-          return true;
-        }
-      }
-      return false;
-    }
-
-    public boolean isAudio() {
-      String extension = getExtension();
-      if (extension != null) {
-        if (extension.equalsIgnoreCase("mp3") ||
-            extension.equalsIgnoreCase("wav") ||
-            extension.equalsIgnoreCase("aac")) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    public boolean isVideo() {
-      String extension = getExtension();
-      if (extension != null) {
-        if (extension.equalsIgnoreCase("mpg") ||
-            extension.equalsIgnoreCase("mpeg") ||
-            extension.equalsIgnoreCase("mpe") ||
-            extension.equalsIgnoreCase("divx") ||
-            extension.equalsIgnoreCase("3gpp") ||
-            extension.equalsIgnoreCase("avi")) {
-          return true;
-        }
-      }
-      return false;
-    }
-
-    public void setParent(boolean isParent) {
-      mIsParent = isParent;
-    }
-
-    public boolean isDirectory() {
-      return mPath.isDirectory();
-    }
-
-    public String getExtension() {
-      if (isDirectory()) {
-        return null;
-      }
-      if (mExtension == null) {
-        String path = getPath();
-        int index = path.lastIndexOf(".");
-        if ((index != -1) && (index != path.length() - 1)){
-          // if we find a dot that is not the last character
-          mExtension = path.substring(index+1);
-          return mExtension;
-        }
-      }
-      return mExtension;
-    }
-
-    public void refresh() {
-      mChildren = null;
-      Vector children = getChildren();
-      mImagesLoader.clearIconRequests();
-    }
-
-    public Vector getChildren() {
-      if (isDirectory()) {
-        if (mChildren == null) {
-          mChildren = new Vector();
-          File[] files = mPath.listFiles();
-          if (mParent != null) {
-            mChildren.add(mParent);
-            mParent.setParent(true);
-          }
-          for (int i = 0; i < files.length; i++) {
-            String name = files[i].getName();
-            String fpath = files[i].getPath();
-            if (!name.startsWith(".")) { // hide dotfiles
-              FilePickerElement elem = new FilePickerElement(fpath, name,
-                                                             mAdapter, this);
-              elem.setParent(false);
-              mChildren.add(elem);
-            }
-          }
-        }
-      }
-      return mChildren;
-    }
-
-    public FilePickerElement getChild(int position) {
-      Vector children = getChildren();
-      if (children != null) {
-        FilePickerElement elem = (FilePickerElement) children.get(position);
-        return elem;
-      }
-      return null;
-    }
-
-    /*
-     * Depending on the type, we return either
-     * the icon (mIcon) or the back icon (mBackIcon).
-     * If we can load a system thumbnail we do this
-     * synchronously and return it, else we ask the
-     * mImagesLoader to generate a thumbnail for us.
-     */
-    public Bitmap getIcon(int position) {
-      if (mIsParent) {
-        return mBackIcon;
-      }
-      if (isImage()) {
-        if (mThumbnail != null) {
-          return mThumbnail;
-        } else {
-          Bitmap image = mImagesLoader.getSystemThumbnail(this);
-          if (image != null) {
-            mThumbnail = image;
-            return mThumbnail;
-          }
-          mImagesLoader.postIconRequest(this, position, true);
-        }
-      }
-      return mIcon;
-    }
-
-    public Bitmap getThumbnail() {
-      return mThumbnail;
-    }
-
-    public void setThumbnail(Bitmap icon) {
-      mThumbnail = icon;
-    }
-
-    public String getName() {
-      return mName;
-    }
-
-    public String getPath() {
-      return mPath.getPath();
-    }
-
-    public void toggleSelection() {
-      mIsSelected = !mIsSelected;
-    }
-
-    public boolean isSelected() {
-      return mIsSelected;
-    }
-
-  }
-
-  /**
-   * Adapter for the GridView
-   */
-  class FilePickerAdapter extends BaseAdapter {
-    private Context mContext;
-    private Map mImagesMap;
-    private Map mImagesSelected;
-
-    private Vector mImages;
-    private Vector<FilePickerElement> mFiles;
-
-    private FilePickerElement mRootElement;
-    private FilePickerElement mCurrentElement;
-
-    public FilePickerAdapter(Context context) {
-      mContext = context;
-      mImages = new Vector();
-      mFiles = new Vector();
-
-      mImagesMap = Collections.synchronizedMap(new HashMap());
-      mImagesSelected = new HashMap();
-
-      String startingPath = Environment.getExternalStorageDirectory().getPath();
-      mRootElement = new FilePickerElement(startingPath, "SD Card", this);
-      mCurrentElement = mRootElement;
-    }
-
-    public void addImage(String path) {
-      mImages.add(path);
-      Bitmap image = BitmapFactory.decodeResource(
-          getResources(), R.drawable.gears_file_unknown);
-      mImagesMap.put(path, image);
-      mImagesSelected.put(path, Boolean.FALSE);
-    }
-
-    public int getCount() {
-      Vector elems = mCurrentElement.getChildren();
-      setCurrentPath(mCurrentElement.getPath());
-      return elems.size();
-    }
-
-    public Object getItem(int position) {
-      return position;
-    }
-
-    public long getItemId(int position) {
-      return position;
-    }
-
-    public Vector selectedElements() {
-      if (mCurrentElement == null) {
-        return null;
-      }
-      Vector children = mCurrentElement.getChildren();
-      Vector ret = new Vector();
-      for (int i = 0; i < children.size(); i++) {
-        FilePickerElement elem = (FilePickerElement) children.get(i);
-        if (elem.isSelected()) {
-          ret.add(elem);
-        }
-      }
-      return ret;
-    }
-
-    public View getView(int position, View convertView, ViewGroup parent) {
-      View cell = convertView;
-      if (cell == null) {
-        LayoutInflater inflater = (LayoutInflater) getSystemService(
-            Context.LAYOUT_INFLATER_SERVICE);
-        cell = inflater.inflate(R.layout.gears_dialog_filepicker_cell, null);
-      }
-      ImageView imageView = (ImageView) cell.findViewById(R.id.icon);
-      TextView textView = (TextView) cell.findViewById(R.id.name);
-      FilePickerElement elem = mCurrentElement.getChild(position);
-      if (elem == null) {
-        String message = "Could not get elem " + position;
-        message += " for " + mCurrentElement.getPath();
-        Log.e(TAG, message);
-        return null;
-      }
-      String path = elem.getPath();
-      textView.setText(elem.getName());
-
-      View.OnClickListener listener = new View.OnClickListener() {
-        public void onClick(View view) {
-          int pos = (Integer) view.getTag();
-          FilePickerElement elem = mCurrentElement.getChild(pos);
-          if (elem.isDirectory()) {
-            mCurrentElement = elem;
-            mCurrentElement.refresh();
-          } else {
-            if (mMultipleSelection) {
-              elem.toggleSelection();
-            } else {
-              Vector elems = selectedElements();
-              if (elems != null) {
-                if (elems.size() == 0) {
-                  elem.toggleSelection();
-                } else if ((elems.size() == 1)
-                           && elem.isSelected()) {
-                  elem.toggleSelection();
-                }
-              }
-            }
-          }
-          setSelectionText();
-          notifyDataSetChanged();
-        }
-      };
-      cell.setLayoutParams(new GridView.LayoutParams(96, 96));
-      cell.setOnClickListener(listener);
-      cell.setOnTouchListener(new View.OnTouchListener() {
-        public boolean onTouch(View v, MotionEvent event) {
-          if (event.getAction() == MotionEvent.ACTION_DOWN) {
-            int color = getResources().getColor(R.color.icon_selection);
-            v.setBackgroundColor(color);
-          } else {
-            v.setBackgroundColor(android.R.color.background_dark);
-          }
-          return false;
-        }
-      });
-
-      cell.setTag(position);
-
-      if (elem.isSelected()) {
-        int color = getResources().getColor(R.color.icon_selection);
-        cell.setBackgroundColor(color);
-      } else {
-        cell.setBackgroundColor(android.R.color.background_dark);
-      }
-      Bitmap bmp = elem.getIcon(position);
-      if (bmp != null) {
-        imageView.setImageBitmap(bmp);
-      }
-
-      return cell;
-    }
-  }
-
-  private String selectedFiles() {
-    Vector selection = mAdapter.selectedElements();
-    JSONArray jsonSelection = new JSONArray();
-    if (selection != null) {
-      for (int i = 0; i < selection.size(); i++) {
-        FilePickerElement elem = (FilePickerElement) selection.get(i);
-        jsonSelection.put(elem.getPath());
-      }
-    }
-    return jsonSelection.toString();
-  }
-
-  public String closeDialog(int closingType) {
-    return selectedFiles();
-  }
-}
diff --git a/src/com/android/browser/GearsNativeDialog.java b/src/com/android/browser/GearsNativeDialog.java
index c72ad8e..ecf166d 100644
--- a/src/com/android/browser/GearsNativeDialog.java
+++ b/src/com/android/browser/GearsNativeDialog.java
@@ -36,8 +36,6 @@
 import com.android.browser.GearsBaseDialog;
 import com.android.browser.GearsPermissionsDialog;
 import com.android.browser.GearsSettingsDialog;
-import com.android.browser.GearsShortcutDialog;
-import com.android.browser.GearsFilePickerDialog;
 
 /**
  * Native dialog Activity used by gears
@@ -57,16 +55,12 @@
   private int mDialogType;
   private final int SETTINGS_DIALOG = 1;
   private final int PERMISSION_DIALOG = 2;
-  private final int SHORTCUT_DIALOG = 3;
-  private final int LOCATION_DIALOG = 4;
-  private final int FILEPICKER_DIALOG = 5;
+  private final int LOCATION_DIALOG = 3;
 
   private final String VERSION_STRING = "version";
   private final String SETTINGS_DIALOG_STRING = "settings_dialog";
   private final String PERMISSION_DIALOG_STRING = "permissions_dialog";
-  private final String SHORTCUT_DIALOG_STRING = "shortcuts_dialog";
   private final String LOCATION_DIALOG_STRING = "locations_dialog";
-  private final String FILEPICKER_DIALOG_STRING = "filepicker_dialog";
 
   private boolean mDialogDismissed = false;
 
@@ -111,15 +105,9 @@
       case PERMISSION_DIALOG:
         dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
         break;
-      case SHORTCUT_DIALOG:
-        dialog = new GearsShortcutDialog(this, mHandler, mDialogArguments);
-        break;
       case LOCATION_DIALOG:
         dialog = new GearsPermissionsDialog(this, mHandler, mDialogArguments);
         break;
-      case FILEPICKER_DIALOG:
-        dialog = new GearsFilePickerDialog(this, mHandler, mDialogArguments);
-        break;
       default:
         dialog = new GearsBaseDialog(this, mHandler, mDialogArguments);
     }
@@ -136,7 +124,7 @@
    */
   private void getArguments() {
     if (mDebug) {
-      mDialogType = FILEPICKER_DIALOG +1;
+      mDialogType = LOCATION_DIALOG +1;
       mockArguments();
 
       return;
@@ -158,12 +146,8 @@
       mGearsVersion = intent.getStringExtra(VERSION_STRING);
     } else if (dialogTypeString.equalsIgnoreCase(PERMISSION_DIALOG_STRING)) {
       mDialogType = PERMISSION_DIALOG;
-    } else if (dialogTypeString.equalsIgnoreCase(SHORTCUT_DIALOG_STRING)) {
-      mDialogType = SHORTCUT_DIALOG;
     } else if (dialogTypeString.equalsIgnoreCase(LOCATION_DIALOG_STRING)) {
       mDialogType = LOCATION_DIALOG;
-    } else if (dialogTypeString.equalsIgnoreCase(FILEPICKER_DIALOG_STRING)) {
-      mDialogType = FILEPICKER_DIALOG;
     }
   }
 
@@ -173,17 +157,6 @@
    * Set mock arguments.
    */
   private void mockArguments() {
-    String argumentsShortcuts = "{ locale: \"en-US\","
-        + "name: \"My Application\", link: \"http://www.google.com/\","
-        + "description: \"This application does things does things!\","
-        + "icon16x16: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/16.png\","
-        + "icon32x32: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/32.png\","
-        + "icon48x48: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/48.png\","
-        + "icon128x128: \"http://google-gears.googlecode.com/"
-        + "svn/trunk/gears/test/manual/shortcuts/128.png\"}";
 
     String argumentsPermissions = "{ locale: \"en-US\", "
         + "origin: \"http://www.google.com\", dialogType: \"localData\","
@@ -215,16 +188,7 @@
         + "localStorage: { permissionState: 2 }, "
         + "locationData: { permissionState: 2 } } ] }";
 
-    String argumentsFilePicker = "{ \"cameraMode\" : \"OFF\", \"filters\""
-        + ": [ \"text/html\", \".txt\" ], \"mode\" : \"MULTIPLE_FILES\" }\"";
-
-    String argumentsFilePicker2 = "{ \"cameraMode\" : \"OFF\", \"filters\""
-        + ": [ \"text/html\", \".txt\" ], \"mode\" : \"SINGLE_FILE\" }\"";
-
     switch (mDialogType) {
-      case SHORTCUT_DIALOG:
-        mDialogArguments = argumentsShortcuts;
-        break;
       case PERMISSION_DIALOG:
         mDialogArguments = argumentsPermissions;
         break;
@@ -234,8 +198,6 @@
       case SETTINGS_DIALOG:
         mDialogArguments = argumentsSettings;
         break;
-      case FILEPICKER_DIALOG:
-        mDialogArguments = argumentsFilePicker2;
     }
   }
 
diff --git a/src/com/android/browser/GearsShortcutDialog.java b/src/com/android/browser/GearsShortcutDialog.java
deleted file mode 100644
index 11d936d..0000000
--- a/src/com/android/browser/GearsShortcutDialog.java
+++ /dev/null
@@ -1,151 +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.View;
-import android.widget.ImageView;
-import android.widget.TextView;
-
-import org.json.JSONException;
-import org.json.JSONObject;
-
-/**
- * Gears Shortcut dialog
- */
-class GearsShortcutDialog extends GearsBaseDialog {
-
-  private static final String TAG = "GearsPermissionsDialog";
-
-  private final String ICON_16 = "icon16x16";
-  private final String ICON_32 = "icon32x32";
-  private final String ICON_48 = "icon48x48";
-  private final String ICON_128 = "icon128x128";
-  private int mNotification = 0;
-
-  public GearsShortcutDialog(Activity activity,
-                             Handler handler,
-                             String arguments) {
-    super (activity, handler, arguments);
-  }
-
-  public void setup() {
-    inflate(R.layout.gears_dialog_shortcut, R.id.panel_content);
-    setupButtons(R.string.shortcut_button_alwaysdeny,
-                 R.string.shortcut_button_allow,
-                 R.string.shortcut_button_deny);
-
-    try {
-      JSONObject json = new JSONObject(mDialogArguments);
-
-      String iconUrl = pickIconToRender(json);
-      if (iconUrl != null) {
-        downloadIcon(iconUrl);
-      }
-
-      setupDialog();
-
-      setLabel(json, "name", R.id.shortcut_name);
-      setLabel(json, "link", R.id.origin_subtitle);
-      setLabel(json, "description", R.id.origin_message);
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception", e);
-    }
-
-    TextView msg = (TextView) findViewById(R.id.permission_dialog_message);
-    msg.setText(R.string.shortcut_message);
-
-    View shortcutIcon = findViewById(R.id.shortcut_panel);
-    if (shortcutIcon != null) {
-      shortcutIcon.setVisibility(View.VISIBLE);
-    }
-  }
-
-  public void setupDialog(TextView message, ImageView icon) {
-    message.setText(R.string.shortcut_prompt);
-    icon.setImageResource(R.drawable.ic_dialog_menu_generic);
-  }
-
-  /**
-   * Utility method to validate an icon url. Used in the
-   * shortcut dialog.
-   */
-  boolean validIcon(JSONObject json, String name) {
-    try {
-      if (json.has(name)) {
-        String str = json.getString(name);
-        if (str.length() > 0) {
-          return true;
-        }
-      }
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception", e);
-    }
-    return false;
-  }
-
-
-  /**
-   * Utility method to pick the best indicated icon
-   * from the dialogs' arguments. Used in the
-   * shortcut dialog.
-   */
-  String pickIconToRender(JSONObject json) {
-    try {
-      if (validIcon(json, ICON_48)) { // ideal size
-        mChoosenIconSize = 48;
-        return json.getString(ICON_48);
-      } else if (validIcon(json, ICON_32)) {
-        mChoosenIconSize = 32;
-        return json.getString(ICON_32);
-      } else if (validIcon(json, ICON_128)) {
-        mChoosenIconSize = 128;
-        return json.getString(ICON_128);
-      } else if (validIcon(json, ICON_16)) {
-        mChoosenIconSize = 16;
-        return json.getString(ICON_16);
-      }
-    } catch (JSONException e) {
-      Log.e(TAG, "JSON exception", e);
-    }
-    mChoosenIconSize = 0;
-    return null;
-  }
-
-  public String closeDialog(int closingType) {
-    String ret = null;
-    switch (closingType) {
-      case ALWAYS_DENY:
-        ret = "{\"allow\": false, \"permanently\": true }";
-        break;
-      case ALLOW:
-        ret = "{\"allow\": true, \"locations\": 0 }";
-        mNotification = R.string.shortcut_notification;
-        break;
-      case DENY:
-        ret = null;
-        break;
-    }
-    return ret;
-  }
-
-  public int notification() {
-    return mNotification;
-  }
-}
