diff --git a/src/com/android/browser/AddBookmarkFolder.java b/src/com/android/browser/AddBookmarkFolder.java
new file mode 100644
index 0000000..7fae373
--- /dev/null
+++ b/src/com/android/browser/AddBookmarkFolder.java
@@ -0,0 +1,951 @@
+/*
+ * Copyright (C) 2006 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.browser;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.app.LoaderManager;
+import android.app.LoaderManager.LoaderCallbacks;
+import android.content.AsyncTaskLoader;
+import android.content.ContentResolver;
+import android.content.ContentUris;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.CursorLoader;
+import android.content.DialogInterface;
+import android.content.Loader;
+import android.content.res.Resources;
+import android.database.Cursor;
+import android.graphics.drawable.Drawable;
+import android.net.Uri;
+import android.os.Bundle;
+import android.provider.BrowserContract;
+import android.provider.BrowserContract.Accounts;
+import android.text.InputFilter;
+import android.text.Spanned;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.KeyEvent;
+import android.view.LayoutInflater;
+import android.view.View;
+import android.view.ViewGroup;
+import android.view.Window;
+import android.view.inputmethod.EditorInfo;
+import android.view.inputmethod.InputMethodManager;
+import android.widget.AdapterView;
+import android.widget.AdapterView.OnItemSelectedListener;
+import android.widget.ArrayAdapter;
+import android.widget.CursorAdapter;
+import android.widget.EditText;
+import android.widget.Spinner;
+import android.widget.TextView;
+import android.widget.Toast;
+
+import com.android.browser.addbookmark.FolderSpinner;
+import com.android.browser.addbookmark.FolderSpinnerAdapter;
+import com.android.browser.provider.BrowserProvider2;
+
+public class AddBookmarkFolder extends Activity implements View.OnClickListener,
+        TextView.OnEditorActionListener, AdapterView.OnItemClickListener,
+        LoaderManager.LoaderCallbacks<Cursor>, BreadCrumbView.Controller,
+        FolderSpinner.OnSetSelectionListener, OnItemSelectedListener {
+
+    public static final long DEFAULT_FOLDER_ID = -1;
+
+    // Place on an edited bookmark to remove the saved thumbnail
+    public static final String CHECK_FOR_DUPE = "check_for_dupe";
+
+    public static final String BOOKMARK_CURRENT_ID = "bookmark_current_id";
+
+    /* package */static final String EXTRA_EDIT_BOOKMARK = "bookmark";
+
+    /* package */static final String EXTRA_IS_FOLDER = "is_folder";
+
+    private static final int MAX_CRUMBS_SHOWN = 2;
+
+    private long mOriginalFolder = -1;
+
+    private boolean mIsFolderChanged = false;
+
+    private boolean mIsOtherFolderSelected = false;
+
+    private boolean mIsRecentFolder = false;
+
+    // IDs for the CursorLoaders that are used.
+    private static final int LOADER_ID_ACCOUNTS = 0;
+
+    private static final int LOADER_ID_FOLDER_CONTENTS = 1;
+
+    private static final int LOADER_ID_EDIT_INFO = 2;
+
+    private EditText mTitle;
+
+    private EditText mAddress;
+
+    private TextView mButton;
+
+    private View mCancelButton;
+
+    private Bundle mMap;
+
+    private FolderSpinner mFolder;
+
+    private View mDefaultView;
+
+    private View mFolderSelector;
+
+    private EditText mFolderNamer;
+
+    private View mFolderCancel;
+
+    private boolean mIsFolderNamerShowing;
+
+    private View mFolderNamerHolder;
+
+    private View mAddNewFolder;
+
+    private View mAddSeparator;
+
+    private long mCurrentFolder;
+
+    private FolderAdapter mAdapter;
+
+    private BreadCrumbView mCrumbs;
+
+    private TextView mFakeTitle;
+
+    private View mCrumbHolder;
+
+    private AddBookmarkPage.CustomListView mListView;
+
+    private long mRootFolder;
+
+    private TextView mTopLevelLabel;
+
+    private Drawable mHeaderIcon;
+
+    private View mRemoveLink;
+
+    private View mFakeTitleHolder;
+
+    private FolderSpinnerAdapter mFolderAdapter;
+
+    private Spinner mAccountSpinner;
+
+    private ArrayAdapter<BookmarkAccount> mAccountAdapter;
+
+
+    private static class Folder {
+        String mName;
+
+        long mId;
+
+        Folder(String name, long id) {
+            mName = name;
+            mId = id;
+        }
+    }
+
+    private InputMethodManager getInputMethodManager() {
+        return (InputMethodManager) getSystemService(INPUT_METHOD_SERVICE);
+    }
+
+    private Uri getUriForFolder(long folder) {
+        BookmarkAccount account = (BookmarkAccount) mAccountSpinner.getSelectedItem();
+        if (folder == mRootFolder && account != null) {
+            return BookmarksLoader.addAccount(BrowserContract.Bookmarks.CONTENT_URI_DEFAULT_FOLDER,
+                    account.mAccountType, account.mAccountName);
+        }
+        return BrowserContract.Bookmarks.buildFolderUri(folder);
+    }
+
+    public static long getIdFromData(Object data) {
+        if (data == null) {
+            return BrowserProvider2.FIXED_ID_ROOT;
+        } else {
+            Folder folder = (Folder) data;
+            return folder.mId;
+        }
+    }
+
+    @Override
+    public void onTop(BreadCrumbView view, int level, Object data) {
+        if (null == data) {
+            return;
+        }
+        Folder folderData = (Folder) data;
+        long folder = folderData.mId;
+        LoaderManager manager = getLoaderManager();
+        CursorLoader loader = (CursorLoader) ((Loader<?>) manager
+                .getLoader(LOADER_ID_FOLDER_CONTENTS));
+        loader.setUri(getUriForFolder(folder));
+        loader.forceLoad();
+        if (mIsFolderNamerShowing) {
+            completeOrCancelFolderNaming(true);
+        }
+        setShowBookmarkIcon(level == 1);
+    }
+
+    /**
+     * Show or hide the icon for bookmarks next to "Bookmarks" in the crumb
+     * view.
+     *
+     * @param show True if the icon should visible, false otherwise.
+     */
+    private void setShowBookmarkIcon(boolean show) {
+        Drawable drawable = show ? mHeaderIcon : null;
+        mTopLevelLabel.setCompoundDrawablesWithIntrinsicBounds(drawable, null, null, null);
+    }
+
+    @Override
+    public boolean onEditorAction(TextView v, int actionId, KeyEvent event) {
+        if (v == mFolderNamer) {
+            if (v.getText().length() > 0) {
+                if (actionId == EditorInfo.IME_NULL) {
+                    // Only want to do this once.
+                    if (event.getAction() == KeyEvent.ACTION_UP) {
+                        completeOrCancelFolderNaming(false);
+                    }
+                }
+            }
+            // Steal the key press; otherwise a newline will be added
+            return true;
+        }
+        return false;
+    }
+
+    private void switchToDefaultView(boolean changedFolder) {
+        mFolderSelector.setVisibility(View.GONE);
+        mDefaultView.setVisibility(View.VISIBLE);
+        mCrumbHolder.setVisibility(View.GONE);
+        mFakeTitleHolder.setVisibility(View.VISIBLE);
+        if (changedFolder) {
+            Object data = mCrumbs.getTopData();
+            if (data != null) {
+                Folder folder = (Folder) data;
+                mCurrentFolder = folder.mId;
+                if (mCurrentFolder == mRootFolder) {
+                    // The Spinner changed to show "Other folder ..." Change
+                    // it back to "Bookmarks", which is position 0 if we are
+                    // editing a folder, 1 otherwise.
+                    mFolder.setSelectionIgnoringSelectionChange(0);
+                } else {
+                    mFolderAdapter.setOtherFolderDisplayText(folder.mName);
+                }
+            }
+        } else {
+            if (mCurrentFolder == mRootFolder) {
+                mFolder.setSelectionIgnoringSelectionChange(0);
+            } else {
+                Object data = mCrumbs.getTopData();
+                if (data != null && ((Folder) data).mId == mCurrentFolder) {
+                    // We are showing the correct folder hierarchy. The
+                    // folder selector will say "Other folder..." Change it
+                    // to say the name of the folder once again.
+                    mFolderAdapter.setOtherFolderDisplayText(((Folder) data).mName);
+                } else {
+                    // We are not showing the correct folder hierarchy.
+                    // Clear the Crumbs and find the proper folder
+                    setupTopCrumb();
+                    LoaderManager manager = getLoaderManager();
+                    manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
+
+                }
+            }
+        }
+    }
+
+    @Override
+    public void onClick(View v) {
+        if (v == mButton) {
+            if (mFolderSelector.getVisibility() == View.VISIBLE) {
+                // We are showing the folder selector.
+                if (mIsFolderNamerShowing) {
+                    completeOrCancelFolderNaming(false);
+                } else {
+                    switchToDefaultView(true);
+                }
+            } else {
+                if (save()) {
+                    finish();
+                }
+            }
+        } else if (v == mCancelButton) {
+            if (mIsFolderNamerShowing) {
+                completeOrCancelFolderNaming(true);
+            } else if (mFolderSelector.getVisibility() == View.VISIBLE) {
+                switchToDefaultView(false);
+            } else {
+                finish();
+            }
+        } else if (v == mFolderCancel) {
+            completeOrCancelFolderNaming(true);
+        }
+    }
+
+    private void displayToastForExistingFolder() {
+        Toast.makeText(getApplicationContext(), R.string.duplicated_folder_warning,
+                Toast.LENGTH_LONG).show();
+    }
+
+    @Override
+    public void onSetSelection(long id) {
+        int intId = (int) id;
+        mIsFolderChanged = true;
+        mIsOtherFolderSelected = false;
+        mIsRecentFolder = false;
+        switch (intId) {
+            case FolderSpinnerAdapter.ROOT_FOLDER:
+                mCurrentFolder = mRootFolder;
+                mOriginalFolder = mCurrentFolder;
+                break;
+            case FolderSpinnerAdapter.HOME_SCREEN:
+
+                break;
+            case FolderSpinnerAdapter.OTHER_FOLDER:
+                mIsOtherFolderSelected = true;
+                switchToFolderSelector();
+                break;
+            case FolderSpinnerAdapter.RECENT_FOLDER:
+                mCurrentFolder = mFolderAdapter.recentFolderId();
+                mOriginalFolder = mCurrentFolder;
+                mIsRecentFolder = true;
+                // In case the user decides to select OTHER_FOLDER
+                // and choose a different one, so that we will start from
+                // the correct place.
+                LoaderManager manager = getLoaderManager();
+                manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Finish naming a folder, and close the IME
+     *
+     * @param cancel If true, the new folder is not created. If false, the new
+     *            folder is created and the user is taken inside it.
+     */
+    private void completeOrCancelFolderNaming(boolean cancel) {
+        if (!cancel && !TextUtils.isEmpty(mFolderNamer.getText())) {
+            String name = mFolderNamer.getText().toString();
+            long id = addFolderToCurrent(mFolderNamer.getText().toString());
+            descendInto(name, id);
+        }
+        setShowFolderNamer(false);
+        getInputMethodManager().hideSoftInputFromWindow(mListView.getWindowToken(), 0);
+    }
+
+    private long addFolderToCurrent(String name) {
+        // Add the folder to the database
+        ContentValues values = new ContentValues();
+        values.put(BrowserContract.Bookmarks.TITLE, name);
+        values.put(BrowserContract.Bookmarks.IS_FOLDER, 1);
+        long currentFolder;
+        Object data = null;
+        if (null != mCrumbs) {
+            data = mCrumbs.getTopData();
+        }
+        if (data != null) {
+            currentFolder = ((Folder) data).mId;
+        } else {
+            currentFolder = mRootFolder;
+        }
+        currentFolder = mCurrentFolder;
+        if (mIsRecentFolder) {
+            values.put(BrowserContract.Bookmarks.PARENT, mCurrentFolder);
+        } else if (!(mIsFolderChanged && mIsOtherFolderSelected) && mOriginalFolder != -1) {
+            values.put(BrowserContract.Bookmarks.PARENT, mOriginalFolder);
+        } else {
+            values.put(BrowserContract.Bookmarks.PARENT, currentFolder);
+        }
+        Uri uri = getContentResolver().insert(BrowserContract.Bookmarks.CONTENT_URI, values);
+        if (uri != null) {
+            return ContentUris.parseId(uri);
+        } else {
+            return -1;
+        }
+    }
+
+    private void switchToFolderSelector() {
+        // Set the list to the top in case it is scrolled.
+        mListView.setSelection(0);
+        mFakeTitleHolder.setVisibility(View.GONE);
+        // mFakeTitle.setVisibility(View.GONE);
+        mDefaultView.setVisibility(View.GONE);
+        mFolderSelector.setVisibility(View.VISIBLE);
+        mCrumbHolder.setVisibility(View.VISIBLE);
+        getInputMethodManager().hideSoftInputFromWindow(mListView.getWindowToken(), 0);
+    }
+
+    private void descendInto(String foldername, long id) {
+        if (id != DEFAULT_FOLDER_ID) {
+            mCrumbs.pushView(foldername, new Folder(foldername, id));
+            mCrumbs.notifyController();
+        } else {
+            Toast.makeText(getApplicationContext(), R.string.duplicated_folder_warning,
+                    Toast.LENGTH_LONG).show();
+        }
+    }
+
+    private LoaderCallbacks<EditBookmarkInfo> mEditInfoLoaderCallbacks = new LoaderCallbacks<EditBookmarkInfo>() {
+
+        @Override
+        public void onLoaderReset(Loader<EditBookmarkInfo> loader) {
+            // Don't care
+        }
+
+        @Override
+        public void onLoadFinished(Loader<EditBookmarkInfo> loader, EditBookmarkInfo info) {
+            boolean setAccount = false;
+            // TODO: Detect if lastUsedId is a subfolder of info.id in the
+            // editing folder case. For now, just don't show the last used
+            // folder at all to prevent any chance of the user adding a parent
+            // folder to a child folder
+            if (info.mLastUsedId != -1 && info.mLastUsedId != info.mId) {
+                if (setAccount && info.mLastUsedId != mRootFolder
+                        && TextUtils.equals(info.mLastUsedAccountName, info.mAccountName)
+                        && TextUtils.equals(info.mLastUsedAccountType, info.mAccountType)) {
+                    mFolderAdapter.addRecentFolder(info.mLastUsedId, info.mLastUsedTitle);
+                } else if (!setAccount) {
+                    setAccount = true;
+                    setAccount(info.mLastUsedAccountName, info.mLastUsedAccountType);
+                    if (info.mLastUsedId != mRootFolder) {
+                        mFolderAdapter.addRecentFolder(info.mLastUsedId, info.mLastUsedTitle);
+                    }
+                }
+            }
+            if (!setAccount) {
+                mAccountSpinner.setSelection(0);
+            }
+        }
+
+        @Override
+        public Loader<EditBookmarkInfo> onCreateLoader(int id, Bundle args) {
+            return new EditBookmarkInfoLoader(AddBookmarkFolder.this, mMap);
+        }
+    };
+
+    void setAccount(String accountName, String accountType) {
+        for (int i = 0; i < mAccountAdapter.getCount(); i++) {
+            BookmarkAccount account = mAccountAdapter.getItem(i);
+            if (TextUtils.equals(account.mAccountName, accountName)
+                    && TextUtils.equals(account.mAccountType, accountType)) {
+                mAccountSpinner.setSelection(i);
+                onRootFolderFound(account.rootFolderId);
+                return;
+            }
+        }
+    }
+
+    @Override
+    public Loader<Cursor> onCreateLoader(int id, Bundle args) {
+        String[] projection;
+        switch (id) {
+            case LOADER_ID_ACCOUNTS:
+                return new AccountsLoader(this);
+            case LOADER_ID_FOLDER_CONTENTS:
+                projection = new String[] {
+                        BrowserContract.Bookmarks._ID, BrowserContract.Bookmarks.TITLE,
+                        BrowserContract.Bookmarks.IS_FOLDER
+                };
+                String where = BrowserContract.Bookmarks.IS_FOLDER + " != 0" + " AND "
+                        + BrowserContract.Bookmarks._ID + " != ?";
+                String whereArgs[] = new String[] {
+                        Long.toString(mMap.getLong(BrowserContract.Bookmarks._ID))
+                };
+                long currentFolder;
+                Object data = mCrumbs.getTopData();
+                if (data != null) {
+                    currentFolder = ((Folder) data).mId;
+                } else {
+                    currentFolder = mRootFolder;
+                }
+                return new CursorLoader(this, getUriForFolder(currentFolder), projection, where,
+                        whereArgs, BrowserContract.Bookmarks._ID + " ASC");
+            default:
+                throw new AssertionError("Asking for nonexistant loader!");
+        }
+    }
+
+    @Override
+    public void onLoadFinished(Loader<Cursor> loader, Cursor cursor) {
+        switch (loader.getId()) {
+            case LOADER_ID_ACCOUNTS:
+                mAccountAdapter.clear();
+                while (cursor.moveToNext()) {
+                    mAccountAdapter.add(new BookmarkAccount(this, cursor));
+                }
+                getLoaderManager().destroyLoader(LOADER_ID_ACCOUNTS);
+                getLoaderManager().restartLoader(LOADER_ID_EDIT_INFO, null,
+                        mEditInfoLoaderCallbacks);
+                break;
+            case LOADER_ID_FOLDER_CONTENTS:
+                mAdapter.changeCursor(cursor);
+                break;
+            default:
+                break;
+        }
+    }
+
+    public void onLoaderReset(Loader<Cursor> loader) {
+        switch (loader.getId()) {
+            case LOADER_ID_FOLDER_CONTENTS:
+                mAdapter.changeCursor(null);
+                break;
+            default:
+                break;
+        }
+    }
+
+    /**
+     * Move cursor to the position that has folderToFind as its "_id".
+     *
+     * @param cursor Cursor containing folders in the bookmarks database
+     * @param folderToFind "_id" of the folder to move to.
+     * @param idIndex Index in cursor of "_id"
+     * @throws AssertionError if cursor is empty or there is no row with
+     *             folderToFind as its "_id".
+     */
+    void moveCursorToFolder(Cursor cursor, long folderToFind, int idIndex) throws AssertionError {
+        if (!cursor.moveToFirst()) {
+            throw new AssertionError("No folders in the database!");
+        }
+        long folder;
+        do {
+            folder = cursor.getLong(idIndex);
+        } while (folder != folderToFind && cursor.moveToNext());
+        if (cursor.isAfterLast()) {
+            throw new AssertionError("Folder(id=" + folderToFind
+                    + ") holding this bookmark does not exist!");
+        }
+    }
+
+    @Override
+    public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
+        TextView tv = (TextView) view.findViewById(android.R.id.text1);
+        // Switch to the folder that was clicked on.
+        descendInto(tv.getText().toString(), id);
+    }
+
+    private void setShowFolderNamer(boolean show) {
+        if (show != mIsFolderNamerShowing) {
+            mIsFolderNamerShowing = show;
+            if (show) {
+                // Set the selection to the folder namer so it will be in
+                // view.
+                mListView.addFooterView(mFolderNamerHolder);
+            } else {
+                mListView.removeFooterView(mFolderNamerHolder);
+            }
+            // Refresh the list.
+            mListView.setAdapter(mAdapter);
+            if (show) {
+                mListView.setSelection(mListView.getCount() - 1);
+            }
+        }
+    }
+
+    /**
+     * Shows a list of names of folders.
+     */
+    private class FolderAdapter extends CursorAdapter {
+        public FolderAdapter(Context context) {
+            super(context, null);
+        }
+
+        @Override
+        public void bindView(View view, Context context, Cursor cursor) {
+            ((TextView) view.findViewById(android.R.id.text1)).setText(cursor.getString(cursor
+                    .getColumnIndexOrThrow(BrowserContract.Bookmarks.TITLE)));
+        }
+
+        @Override
+        public View newView(Context context, Cursor cursor, ViewGroup parent) {
+            View view = LayoutInflater.from(context).inflate(R.layout.folder_list_item, null);
+            view.setBackgroundDrawable(context.getResources().getDrawable(
+                    android.R.drawable.list_selector_background));
+            return view;
+        }
+
+        @Override
+        public boolean isEmpty() {
+            // Do not show the empty view if the user is creating a new folder.
+            return super.isEmpty() && !mIsFolderNamerShowing;
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle icicle) {
+        super.onCreate(icicle);
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
+
+        mMap = getIntent().getExtras();
+
+        setContentView(R.layout.browser_add_bookmark);
+
+        Window window = getWindow();
+
+        String title = this.getString(R.string.new_folder);
+        mFakeTitle = (TextView) findViewById(R.id.fake_title);
+        mFakeTitleHolder = findViewById(R.id.title_holder);
+        mFakeTitle.setText(this.getString(R.string.new_folder));
+
+        mTitle = (EditText) findViewById(R.id.title);
+        // add for cmcc test about waring limit of edit text
+        BrowserUtils.maxLengthFilter(AddBookmarkFolder.this, mTitle, BrowserUtils.FILENAME_MAX_LENGTH);
+
+        mTitle.setText(title);
+        mAddress = (EditText) findViewById(R.id.address);
+        mAddress.setVisibility(View.GONE);
+        findViewById(R.id.row_address).setVisibility(View.GONE);
+
+        mButton = (TextView) findViewById(R.id.OK);
+        mButton.setOnClickListener(this);
+
+        mCancelButton = findViewById(R.id.cancel);
+        mCancelButton.setOnClickListener(this);
+
+        mFolder = (FolderSpinner) findViewById(R.id.folder);
+        mFolderAdapter = new FolderSpinnerAdapter(this, false);
+        mFolder.setAdapter(mFolderAdapter);
+        mFolder.setOnSetSelectionListener(this);
+
+        mDefaultView = findViewById(R.id.default_view);
+        mFolderSelector = findViewById(R.id.folder_selector);
+
+        mFolderNamerHolder = getLayoutInflater().inflate(R.layout.new_folder_layout, null);
+        mFolderNamer = (EditText) mFolderNamerHolder.findViewById(R.id.folder_namer);
+        mFolderNamer.setOnEditorActionListener(this);
+        mFolderCancel = mFolderNamerHolder.findViewById(R.id.close);
+        mFolderCancel.setOnClickListener(this);
+
+        mAddNewFolder = findViewById(R.id.add_new_folder);
+        mAddNewFolder.setVisibility(View.GONE);
+        mAddSeparator = findViewById(R.id.add_divider);
+        mAddSeparator.setVisibility(View.GONE);
+
+        mCrumbs = (BreadCrumbView) findViewById(R.id.crumbs);
+        mCrumbs.setUseBackButton(true);
+        mCrumbs.setController(this);
+        mHeaderIcon = getResources().getDrawable(R.drawable.ic_folder_holo_dark);
+        mCrumbHolder = findViewById(R.id.crumb_holder);
+        mCrumbs.setMaxVisible(MAX_CRUMBS_SHOWN);
+
+        mAdapter = new FolderAdapter(this);
+        mListView = (AddBookmarkPage.CustomListView) findViewById(R.id.list);
+        View empty = findViewById(R.id.empty);
+        mListView.setEmptyView(empty);
+        mListView.setAdapter(mAdapter);
+        mListView.setOnItemClickListener(this);
+        mListView.addEditText(mFolderNamer);
+
+        mAccountAdapter = new ArrayAdapter<BookmarkAccount>(this,
+                android.R.layout.simple_spinner_item);
+        mAccountAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        mAccountSpinner = (Spinner) findViewById(R.id.accounts);
+        mAccountSpinner.setAdapter(mAccountAdapter);
+        mAccountSpinner.setOnItemSelectedListener(this);
+
+        if (!window.getDecorView().isInTouchMode()) {
+            mButton.requestFocus();
+        }
+        // getLoaderManager().restartLoader(LOADER_ID_ACCOUNTS, null, this);
+
+        setShowFolderNamer(false);
+        mFolderNamer.setText(R.string.new_folder);
+        mFolderNamer.requestFocus();
+        InputMethodManager imm = getInputMethodManager();
+        imm.focusIn(mListView);
+        imm.showSoftInput(mFolderNamer, InputMethodManager.SHOW_IMPLICIT);
+
+        mCurrentFolder = getIntent().getLongExtra(
+                BrowserContract.Bookmarks.PARENT, DEFAULT_FOLDER_ID);
+        mOriginalFolder = mCurrentFolder;
+        if (!(mCurrentFolder == -1 || mCurrentFolder == 1)) {
+            mFolder.setSelectionIgnoringSelectionChange(1);
+            mFolderAdapter.setOtherFolderDisplayText(getNameFromId(mOriginalFolder));
+        }
+
+        getLoaderManager().restartLoader(LOADER_ID_ACCOUNTS, null, this);
+    }
+
+    // get folder title from folder id
+    private String getNameFromId(long mCurrentFolder2) {
+        String title = "";
+        Cursor cursor = null;
+        try {
+            cursor = getApplicationContext().getContentResolver().query(
+                    BrowserContract.Bookmarks.CONTENT_URI,
+                    new String[] {
+                        BrowserContract.Bookmarks.TITLE
+                    },
+                    BrowserContract.Bookmarks._ID + " = ? AND "
+                            + BrowserContract.Bookmarks.IS_DELETED + " = ? AND "
+                            + BrowserContract.Bookmarks.IS_FOLDER + " = ? ", new String[] {
+                            String.valueOf(mCurrentFolder2), 0 + "", 1 + ""
+                    }, null);
+            if (cursor != null && cursor.getCount() != 0) {
+                while (cursor.moveToNext()) {
+                    title = cursor.getString(0);
+                }
+            }
+        } finally {
+            if (cursor != null) {
+                cursor.close();
+            }
+        }
+        return title;
+    }
+
+    private void showRemoveButton() {
+        findViewById(R.id.remove_divider).setVisibility(View.VISIBLE);
+        mRemoveLink = findViewById(R.id.remove);
+        mRemoveLink.setVisibility(View.VISIBLE);
+        mRemoveLink.setOnClickListener(this);
+    }
+
+    // Called once we have determined which folder is the root folder
+    private void onRootFolderFound(long root) {
+        mRootFolder = root;
+        mCurrentFolder = mRootFolder;
+        setupTopCrumb();
+        onCurrentFolderFound();
+    }
+
+    private void setupTopCrumb() {
+        mCrumbs.clear();
+        String name = getString(R.string.bookmarks);
+        mTopLevelLabel = (TextView) mCrumbs.pushView(name, false, new Folder(name, mRootFolder));
+        // To better match the other folders.
+        mTopLevelLabel.setCompoundDrawablePadding(6);
+    }
+
+    private void onCurrentFolderFound() {
+        LoaderManager manager = getLoaderManager();
+        if (mCurrentFolder != mRootFolder) {
+            // Since we're not in the root folder, change the selection to other
+            // folder now. The text will get changed once we select the correct
+            // folder.
+            mFolder.setSelectionIgnoringSelectionChange(1);
+        } else {
+            setShowBookmarkIcon(true);
+        }
+        // Find the contents of the current folder
+        manager.restartLoader(LOADER_ID_FOLDER_CONTENTS, null, this);
+    }
+
+    /**
+     * Parse the data entered in the dialog and post a message to update the
+     * bookmarks database.
+     */
+    private boolean save() {
+        String title = mTitle.getText().toString().trim();
+
+        boolean emptyTitle = title.length() == 0;
+        Resources r = getResources();
+        if (emptyTitle) {
+            mTitle.setError(r.getText(R.string.bookmark_needs_title));
+            return false;
+        }
+
+        long id = addFolderToCurrent(title);
+        if (id == -1) {
+            displayToastForExistingFolder();
+            return false;
+        }
+
+        setResult(RESULT_OK);
+        return true;
+    }
+
+    @Override
+    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
+        if (mAccountSpinner == parent) {
+            long root = mAccountAdapter.getItem(position).rootFolderId;
+            if (root != mRootFolder) {
+                onRootFolderFound(root);
+                mFolderAdapter.clearRecentFolder();
+            }
+        }
+    }
+
+    @Override
+    public void onNothingSelected(AdapterView<?> parent) {
+        // Don't care
+    }
+
+    static class AccountsLoader extends CursorLoader {
+
+        static final String[] PROJECTION = new String[] {
+                Accounts.ACCOUNT_NAME, Accounts.ACCOUNT_TYPE, Accounts.ROOT_ID,
+        };
+
+        static final int COLUMN_INDEX_ACCOUNT_NAME = 0;
+
+        static final int COLUMN_INDEX_ACCOUNT_TYPE = 1;
+
+        static final int COLUMN_INDEX_ROOT_ID = 2;
+
+        public AccountsLoader(Context context) {
+            super(context, Accounts.CONTENT_URI, PROJECTION, null, null, null);
+        }
+
+    }
+
+    public static class BookmarkAccount {
+
+        private String mLabel;
+
+        String mAccountName;
+        String mAccountType;
+
+        public long rootFolderId;
+
+        public BookmarkAccount(Context context, Cursor cursor) {
+            mAccountName = cursor.getString(AccountsLoader.COLUMN_INDEX_ACCOUNT_NAME);
+            mAccountType = cursor.getString(AccountsLoader.COLUMN_INDEX_ACCOUNT_TYPE);
+            rootFolderId = cursor.getLong(AccountsLoader.COLUMN_INDEX_ROOT_ID);
+            mLabel = mAccountName;
+            if (TextUtils.isEmpty(mLabel)) {
+                mLabel = context.getString(R.string.local_bookmarks);
+            }
+        }
+
+        @Override
+        public String toString() {
+            return mLabel;
+        }
+    }
+
+    static class EditBookmarkInfo {
+        long mId = -1;
+
+        long mParentId = -1;
+
+        String mParentTitle;
+
+        String mEBITitle;
+
+        String mAccountName;
+
+        String mAccountType;
+
+        long mLastUsedId = -1;
+
+        String mLastUsedTitle;
+
+        String mLastUsedAccountName;
+
+        String mLastUsedAccountType;
+    }
+
+    static class EditBookmarkInfoLoader extends AsyncTaskLoader<EditBookmarkInfo> {
+
+        private Context mContext;
+
+        private Bundle mMap;
+
+        public EditBookmarkInfoLoader(Context context, Bundle bundle) {
+            super(context);
+            mContext = context.getApplicationContext();
+            mMap = bundle;
+        }
+
+        @Override
+        public EditBookmarkInfo loadInBackground() {
+            final ContentResolver cr = mContext.getContentResolver();
+            EditBookmarkInfo info = new EditBookmarkInfo();
+            Cursor c = null;
+            try {
+                // First, let's lookup the bookmark (check for dupes, get needed
+                // info)
+                String url = mMap.getString(BrowserContract.Bookmarks.URL);
+                info.mId = mMap.getLong(BrowserContract.Bookmarks._ID, -1);
+                boolean checkForDupe = mMap.getBoolean(CHECK_FOR_DUPE);
+                if (checkForDupe && info.mId == -1 && !TextUtils.isEmpty(url)) {
+                    c = cr.query(BrowserContract.Bookmarks.CONTENT_URI, new String[] {
+                            BrowserContract.Bookmarks._ID
+                    }, BrowserContract.Bookmarks.URL + "=?", new String[] {
+                            url
+                    }, null);
+                    if (c.getCount() == 1 && c.moveToFirst()) {
+                        info.mId = c.getLong(0);
+                    }
+                    c.close();
+                }
+                if (info.mId != -1) {
+                    c = cr.query(ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
+                            info.mId), new String[] {
+                            BrowserContract.Bookmarks.PARENT,
+                            BrowserContract.Bookmarks.ACCOUNT_NAME,
+                            BrowserContract.Bookmarks.ACCOUNT_TYPE, BrowserContract.Bookmarks.TITLE
+                    }, null, null, null);
+                    if (c.moveToFirst()) {
+                        info.mParentId = c.getLong(0);
+                        info.mAccountName = c.getString(1);
+                        info.mAccountType = c.getString(2);
+                        info.mEBITitle = c.getString(3);
+                    }
+                    c.close();
+                    c = cr.query(ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI,
+                            info.mParentId), new String[] {
+                            BrowserContract.Bookmarks.TITLE,
+                    }, null, null, null);
+                    if (c.moveToFirst()) {
+                        info.mParentTitle = c.getString(0);
+                    }
+                    c.close();
+                }
+
+                // Figure out the last used folder/account
+                c = cr.query(BrowserContract.Bookmarks.CONTENT_URI, new String[] {
+                        BrowserContract.Bookmarks.PARENT,
+                }, null, null, BrowserContract.Bookmarks.DATE_MODIFIED + " DESC LIMIT 1");
+                if (c.moveToFirst()) {
+                    long parent = c.getLong(0);
+                    c.close();
+                    c = cr.query(BrowserContract.Bookmarks.CONTENT_URI, new String[] {
+                            BrowserContract.Bookmarks.TITLE,
+                            BrowserContract.Bookmarks.ACCOUNT_NAME,
+                            BrowserContract.Bookmarks.ACCOUNT_TYPE
+                    }, BrowserContract.Bookmarks._ID + "=?", new String[] {
+                            Long.toString(parent)
+                    }, null);
+                    if (c.moveToFirst()) {
+                        info.mLastUsedId = parent;
+                        info.mLastUsedTitle = c.getString(0);
+                        info.mLastUsedAccountName = c.getString(1);
+                        info.mLastUsedAccountType = c.getString(2);
+                    }
+                    c.close();
+                }
+            } finally {
+                if (c != null) {
+                    c.close();
+                }
+            }
+            return info;
+        }
+
+        @Override
+        protected void onStartLoading() {
+            forceLoad();
+        }
+    }
+}
diff --git a/src/com/android/browser/AddBookmarkPage.java b/src/com/android/browser/AddBookmarkPage.java
index fdb34c4..580723c 100644
--- a/src/com/android/browser/AddBookmarkPage.java
+++ b/src/com/android/browser/AddBookmarkPage.java
@@ -16,10 +16,8 @@
 
 package com.android.browser;
 
-import com.android.browser.addbookmark.FolderSpinner;
-import com.android.browser.addbookmark.FolderSpinnerAdapter;
-
 import android.app.Activity;
+import android.app.AlertDialog;
 import android.app.LoaderManager;
 import android.app.LoaderManager.LoaderCallbacks;
 import android.content.AsyncTaskLoader;
@@ -28,6 +26,7 @@
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.CursorLoader;
+import android.content.DialogInterface;
 import android.content.Loader;
 import android.content.res.Resources;
 import android.database.Cursor;
@@ -40,6 +39,7 @@
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.provider.Browser;
 import android.provider.BrowserContract;
 import android.provider.BrowserContract.Accounts;
 import android.text.TextUtils;
@@ -62,6 +62,10 @@
 import android.widget.TextView;
 import android.widget.Toast;
 
+import com.android.browser.BrowserUtils;
+import com.android.browser.addbookmark.FolderSpinner;
+import com.android.browser.addbookmark.FolderSpinnerAdapter;
+
 import java.net.URI;
 import java.net.URISyntaxException;
 
@@ -123,6 +127,9 @@
     private FolderSpinnerAdapter mFolderAdapter;
     private Spinner mAccountSpinner;
     private ArrayAdapter<BookmarkAccount> mAccountAdapter;
+    // add for carrier which requires same title or address can not exist.
+    private long mDuplicateId;
+    private Context mDuplicateContext;
 
     private static class Folder {
         String Name;
@@ -256,8 +263,16 @@
                     mSaveToHomeScreen = false;
                     switchToDefaultView(true);
                 }
-            } else if (save()) {
-                finish();
+            } else {
+                // add for carrier which requires same title or address can not
+                // exist.
+                if (mSaveToHomeScreen) {
+                    if (save()) {
+                        return;
+                    }
+                } else {
+                    onSaveWithConfirm();
+                }
             }
         } else if (v == mCancelButton) {
             if (mIsFolderNamerShowing) {
@@ -638,9 +653,11 @@
 
         mTitle = (EditText) findViewById(R.id.title);
         mTitle.setText(title);
+        BrowserUtils.maxLengthFilter(AddBookmarkPage.this, mTitle, BrowserUtils.FILENAME_MAX_LENGTH);
 
         mAddress = (EditText) findViewById(R.id.address);
         mAddress.setText(url);
+        BrowserUtils.maxLengthFilter(AddBookmarkPage.this, mAddress, BrowserUtils.ADDRESS_MAX_LENGTH);
 
         mButton = (TextView) findViewById(R.id.OK);
         mButton.setOnClickListener(this);
@@ -659,6 +676,11 @@
         mFolderNamerHolder = getLayoutInflater().inflate(R.layout.new_folder_layout, null);
         mFolderNamer = (EditText) mFolderNamerHolder.findViewById(R.id.folder_namer);
         mFolderNamer.setOnEditorActionListener(this);
+
+        // add for carrier test about warning limit of edit text
+        BrowserUtils.maxLengthFilter(AddBookmarkPage.this, mFolderNamer,
+                BrowserUtils.FILENAME_MAX_LENGTH);
+
         mFolderCancel = mFolderNamerHolder.findViewById(R.id.close);
         mFolderCancel.setOnClickListener(this);
 
@@ -835,6 +857,72 @@
         }
     }
 
+    static void deleteDuplicateBookmark(final Context context, final long id) {
+        Uri uri = ContentUris.withAppendedId(BrowserContract.Bookmarks.CONTENT_URI, id);
+        context.getContentResolver().delete(uri, null, null);
+    }
+
+    private void onSaveWithConfirm() {
+        String title = mTitle.getText().toString().trim();
+        String unfilteredUrl = UrlUtils.fixUrl(mAddress.getText().toString());
+        String url = unfilteredUrl.trim();
+        Long id = mMap.getLong(BrowserContract.Bookmarks._ID);
+        int duplicateCount;
+        final ContentResolver cr = getContentResolver();
+
+        Cursor cursor = cr.query(BrowserContract.Bookmarks.CONTENT_URI,
+                BookmarksLoader.PROJECTION,
+                "( title = ? OR url = ? ) AND parent = ?",
+                new String[] {
+                        title, url, Long.toString(mCurrentFolder)
+                },
+                null);
+
+        if (cursor == null) {
+            save();
+            return;
+        }
+
+        duplicateCount = cursor.getCount();
+        if (duplicateCount <= 0) {
+            cursor.close();
+            save();
+            return;
+        } else {
+            try {
+                while (cursor.moveToNext()) {
+                    mDuplicateId = cursor.getLong(BookmarksLoader.COLUMN_INDEX_ID);
+                    mDuplicateContext = AddBookmarkPage.this;
+                }
+            } catch (IllegalStateException e) {
+                e.printStackTrace();
+            } finally {
+                if (cursor != null)
+                    cursor.close();
+            }
+        }
+
+        if (mEditingExisting && duplicateCount == 1 && mDuplicateId == id) {
+            save();
+            return;
+        }
+
+        new AlertDialog.Builder(this)
+                .setTitle(getString(R.string.save_to_bookmarks_title))
+                .setMessage(getString(R.string.overwrite_bookmark_msg))
+                .setNegativeButton(android.R.string.cancel, null)
+                .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
+                    public void onClick(DialogInterface dialog, int which) {
+                        if (mDuplicateContext == null) {
+                            return;
+                        }
+                        deleteDuplicateBookmark(mDuplicateContext, mDuplicateId);
+                        save();
+                    }
+                })
+                .show();
+    }
+
     /**
      * Parse the data entered in the dialog and post a message to update the bookmarks database.
      */
@@ -842,8 +930,7 @@
         createHandler();
 
         String title = mTitle.getText().toString().trim();
-        String unfilteredUrl;
-        unfilteredUrl = UrlUtils.fixUrl(mAddress.getText().toString());
+        String unfilteredUrl = UrlUtils.fixUrl(mAddress.getText().toString());
 
         boolean emptyTitle = title.length() == 0;
         boolean emptyUrl = unfilteredUrl.trim().length() == 0;
@@ -856,7 +943,6 @@
                 mAddress.setError(r.getText(R.string.bookmark_needs_url));
             }
             return false;
-
         }
         String url = unfilteredUrl.trim();
         if (!mEditingFolder) {
@@ -958,6 +1044,7 @@
             setResult(RESULT_OK);
             LogTag.logBookmarkAdded(url, "bookmarkview");
         }
+        finish();
         return true;
     }
 
diff --git a/src/com/android/browser/BrowserBookmarksPage.java b/src/com/android/browser/BrowserBookmarksPage.java
index b11162c..0d31017 100644
--- a/src/com/android/browser/BrowserBookmarksPage.java
+++ b/src/com/android/browser/BrowserBookmarksPage.java
@@ -41,6 +41,7 @@
 import android.view.ContextMenu;
 import android.view.ContextMenu.ContextMenuInfo;
 import android.view.LayoutInflater;
+import android.view.Menu;
 import android.view.MenuInflater;
 import android.view.MenuItem;
 import android.view.View;
@@ -88,6 +89,8 @@
     static final String ACCOUNT_TYPE = "account_type";
     static final String ACCOUNT_NAME = "account_name";
 
+    static final long DEFAULT_FOLDER_ID = -1;
+
     BookmarksPageCallbacks mCallbacks;
     View mRoot;
     BookmarkExpandableView mGrid;
@@ -97,6 +100,7 @@
     View mHeader;
     HashMap<Integer, BrowserBookmarksAdapter> mBookmarkAdapters = new HashMap<Integer, BrowserBookmarksAdapter>();
     JSONObject mState;
+    long mCurrentFolderId = BrowserProvider2.FIXED_ID_ROOT;
 
     @Override
     public Loader<Cursor> onCreateLoader(int id, Bundle args) {
@@ -147,6 +151,9 @@
         } else if (loader.getId() >= LOADER_BOOKMARKS) {
             BrowserBookmarksAdapter adapter = mBookmarkAdapters.get(loader.getId());
             adapter.changeCursor(cursor);
+            if (adapter.getCount() != 0) {
+                mCurrentFolderId = adapter.getItem(0).getLong(BookmarksLoader.COLUMN_INDEX_PARENT);
+            }
         }
     }
 
@@ -158,6 +165,31 @@
         }
     }
 
+    //add for carrier feature which adds new bookmark/folder function.
+    @Override
+    public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
+        super.onCreateOptionsMenu(menu, inflater);
+        inflater.inflate(R.menu.bookmark, menu);
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        final Activity activity = getActivity();
+        if (item.getItemId() == R.id.add_bookmark_menu_id) {
+            Intent intent = new Intent(activity, AddBookmarkPage.class);
+            intent.putExtra(BrowserContract.Bookmarks.URL, "http://");
+            intent.putExtra(BrowserContract.Bookmarks.TITLE, "");
+            intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+            activity.startActivity(intent);
+        }
+        if (item.getItemId() == R.id.new_bmfolder_menu_id) {
+            Intent intent = new Intent(activity, AddBookmarkFolder.class);
+            intent.putExtra(BrowserContract.Bookmarks.PARENT, mCurrentFolderId);
+            activity.startActivity(intent);
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
     @Override
     public boolean onContextItemSelected(MenuItem item) {
         if (!(item.getMenuInfo() instanceof BookmarkContextMenuInfo)) {
@@ -444,6 +476,9 @@
                 // update crumbs
                 crumbs.pushView(title, uri);
                 crumbs.setVisibility(View.VISIBLE);
+                Object data = crumbs.getTopData();
+                mCurrentFolderId = (data != null ? ContentUris.parseId((Uri) data)
+                        : DEFAULT_FOLDER_ID);
             }
             loadFolder(groupPosition, uri);
         }
diff --git a/src/com/android/browser/BrowserUtils.java b/src/com/android/browser/BrowserUtils.java
new file mode 100644
index 0000000..e1a3600
--- /dev/null
+++ b/src/com/android/browser/BrowserUtils.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2013, The Linux Foundation. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *         copyright notice, this list of conditions and the following
+ *         disclaimer in the documentation and/or other materials provided
+ *         with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *         contributors may be used to endorse or promote products derived
+ *         from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+package com.android.browser;
+
+import android.app.AlertDialog;
+import android.content.Context;
+import android.content.DialogInterface;
+import android.text.InputFilter;
+import android.text.Spanned;
+import android.util.Log;
+import android.widget.EditText;
+
+public class BrowserUtils {
+
+    private static final String LOGTAG = "BrowserUtils";
+    public static final int FILENAME_MAX_LENGTH = 32;
+    public static final int ADDRESS_MAX_LENGTH = 2048;
+    private static AlertDialog.Builder mAlertDialog = null;
+
+    public static void maxLengthFilter(final Context context, final EditText editText,
+            final int max_length) {
+        InputFilter[] contentFilters = new InputFilter[1];
+        contentFilters[0] = new InputFilter.LengthFilter(max_length) {
+            public CharSequence filter(CharSequence source, int start, int end,
+                    Spanned dest, int dstart, int dend) {
+                int keep = max_length - (dest.length() - (dend - dstart));
+                if (keep <= 0) {
+                    showWarningDialog(context, max_length);
+                    return "";
+                } else if (keep >= end - start) {
+                    return null;
+                } else {
+                    if (keep < source.length()) {
+                        showWarningDialog(context, max_length);
+                    }
+                    return source.subSequence(start, start + keep);
+                }
+            }
+        };
+        editText.setFilters(contentFilters);
+    }
+
+    private static void showWarningDialog(final Context context, int max_length) {
+        if (mAlertDialog != null)
+            return;
+
+        mAlertDialog = new AlertDialog.Builder(context);
+        mAlertDialog.setTitle(R.string.browser_max_input_title)
+                .setIcon(android.R.drawable.ic_dialog_info)
+                .setMessage(context.getString(R.string.browser_max_input, max_length))
+                .setPositiveButton(R.string.ok,
+                        new DialogInterface.OnClickListener() {
+                            public void onClick(DialogInterface dialog, int which) {
+                                return;
+                            }
+                        })
+                .show()
+                .setOnDismissListener(new DialogInterface.OnDismissListener() {
+                    public void onDismiss(DialogInterface dialog) {
+                        Log.w("BrowserUtils", "onDismiss");
+                        mAlertDialog = null;
+                        return;
+                    }
+                });
+    }
+}
