diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 13f13b3..14ec59e 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -201,6 +201,16 @@
         <activity android:name="ComboViewActivity">
         </activity>
 
+        <!-- used to new folder in bookmark page for carrier -->
+        <activity android:name="AddBookmarkFolder" android:label="@string/save_bookmark_folder"
+                  android:theme="@style/DialogWhenLarge"
+                  android:configChanges="orientation|keyboardHidden|screenSize">
+            <intent-filter>
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/bookmark"/>
+            </intent-filter>
+        </activity>
+
         <!-- Bookmark thumbnail homescreen widget -->
         <receiver
             android:name=".widget.BookmarkThumbnailWidgetProvider"
diff --git a/res/menu/bookmark.xml b/res/menu/bookmark.xml
new file mode 100644
index 0000000..b43d7ce
--- /dev/null
+++ b/res/menu/bookmark.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<menu xmlns:android="http://schemas.android.com/apk/res/android">
+    <item android:id="@+id/add_bookmark_menu_id"
+        android:title="@string/add_new_bookmark"
+        android:icon="@drawable/ic_add_string"/>
+    <item android:id="@+id/new_bmfolder_menu_id"
+        android:title="@string/new_folder"
+        android:icon="@drawable/ic_add_string"/>
+</menu>
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index d0b8452..84f117c 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -424,4 +424,12 @@
     <string name="exit_browser_msg">请选择退出浏览器的方式？</string>
     <string name="exit_minimize">最小化</string>
     <string name="exit_quit">退出</string>
+
+    <!-- Add for new bookmark/folder Feature -->
+    <string name="save_bookmark_folder">新建书签文件夹</string>
+    <string name="browser_max_input_title">已达输入上限</string>
+    <string name="browser_max_input">您输入的字符数已经达到最大长度<xliff:g id="MAXLIMIT">%s</xliff:g>个字符。</string>
+    <string name="save_to_bookmarks_title">保存书签</string>
+    <string name="duplicated_folder_warning">该文件夹已经存在</string>
+    <string name="overwrite_bookmark_msg">该书签的标签或者地址已经存在，是否覆盖？</string>
 </resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 5167822..cf8d0ab 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -1038,4 +1038,12 @@
     <string name="exit_browser_msg">Please Select How to Exit Browser?</string>
     <string name="exit_minimize">Minimize</string>
     <string name="exit_quit">Quit</string>
+
+    <!-- Add for new bookmark/folder Feature -->
+    <string name="save_bookmark_folder">New folder</string>
+    <string name="browser_max_input_title">Reached Input Limit</string>
+    <string name="browser_max_input">Your input has reached the maximum limit of <xliff:g id="MAXLIMIT">%s</xliff:g> characters.</string>
+    <string name="save_to_bookmarks_title">Save to Bookmarks</string>
+    <string name="duplicated_folder_warning">The folder has already exists</string>
+    <string name="overwrite_bookmark_msg">This bookmark\'s name or address already exists, overwrite it?</string>
 </resources>
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;
+                    }
+                });
+    }
+}
