diff --git a/Android.mk b/Android.mk
index 321bafd..16d0c18 100644
--- a/Android.mk
+++ b/Android.mk
@@ -13,21 +13,15 @@
 # the License.
 
 LOCAL_PATH:= $(call my-dir)
+
 include $(CLEAR_VARS)
 
 LOCAL_MODULE_TAGS := optional
 
-LOCAL_STATIC_JAVA_LIBRARIES := \
-        android-common \
-
 LOCAL_SRC_FILES := \
         $(call all-java-files-under, src)
 
 LOCAL_PACKAGE_NAME := BookmarkProvider
 
-LOCAL_EMMA_COVERAGE_FILTER := *,-com.android.common.*
-
 include $(BUILD_PACKAGE)
 
-# additionally, build tests in sub-folders in a separate .apk
-include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 558cd7e..91d4700 100644
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -15,24 +15,13 @@
 
 <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.android.bookmarkprovider">
 
-    <!-- Required for getAccountsByType, getAccounts -->
-    <uses-permission android:name="android.permission.GET_ACCOUNTS" />
-    <!-- Required for getIsSyncable -->
-    <uses-permission android:name="android.permission.READ_SYNC_SETTINGS" />
-    <!-- Required for setIsSyncable, setSyncAutomatically -->
-    <uses-permission android:name="android.permission.WRITE_SYNC_SETTINGS" />
-
     <application android:label="@string/application_name"
                  android:icon="@mipmap/ic_launcher_shortcut_browser_bookmark" >
 
         <provider android:name=".BookmarkProvider"
-                  android:authorities="com.android.browser;browser"
+                  android:authorities="com.android.browser;browser;com.android.chrome.browser"
                   android:multiprocess="false"
-                  android:exported="true"
-                  android:readPermission="com.android.browser.permission.READ_HISTORY_BOOKMARKS"
-                  android:writePermission="com.android.browser.permission.WRITE_HISTORY_BOOKMARKS">
-            <path-permission android:path="/bookmarks/search_suggest_query"
-                    android:readPermission="android.permission.GLOBAL_SEARCH" />
+                  android:exported="true">
         </provider>
 
     </application>
diff --git a/res/drawable-hdpi/ic_bookmark_off_holo_dark.png b/res/drawable-hdpi/ic_bookmark_off_holo_dark.png
deleted file mode 100644
index f827be5..0000000
--- a/res/drawable-hdpi/ic_bookmark_off_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_history_holo_dark.png b/res/drawable-hdpi/ic_history_holo_dark.png
deleted file mode 100644
index 4f2ee7d..0000000
--- a/res/drawable-hdpi/ic_history_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_search_category_bookmark.png b/res/drawable-hdpi/ic_search_category_bookmark.png
deleted file mode 100644
index bdecfd0..0000000
--- a/res/drawable-hdpi/ic_search_category_bookmark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_search_category_history.png b/res/drawable-hdpi/ic_search_category_history.png
deleted file mode 100644
index 94c89ae..0000000
--- a/res/drawable-hdpi/ic_search_category_history.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-hdpi/ic_search_category_suggest.png b/res/drawable-hdpi/ic_search_category_suggest.png
deleted file mode 100644
index 165a11d..0000000
--- a/res/drawable-hdpi/ic_search_category_suggest.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_bookmark_off_holo_dark.png b/res/drawable-mdpi/ic_bookmark_off_holo_dark.png
deleted file mode 100644
index 825970c..0000000
--- a/res/drawable-mdpi/ic_bookmark_off_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_history_holo_dark.png b/res/drawable-mdpi/ic_history_holo_dark.png
deleted file mode 100644
index 0e4e118..0000000
--- a/res/drawable-mdpi/ic_history_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_search_category_bookmark.png b/res/drawable-mdpi/ic_search_category_bookmark.png
deleted file mode 100644
index cdf4be1..0000000
--- a/res/drawable-mdpi/ic_search_category_bookmark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_search_category_history.png b/res/drawable-mdpi/ic_search_category_history.png
deleted file mode 100644
index 0f63144..0000000
--- a/res/drawable-mdpi/ic_search_category_history.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-mdpi/ic_search_category_suggest.png b/res/drawable-mdpi/ic_search_category_suggest.png
deleted file mode 100644
index 0f04fc4..0000000
--- a/res/drawable-mdpi/ic_search_category_suggest.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_bookmark_off_holo_dark.png b/res/drawable-xhdpi/ic_bookmark_off_holo_dark.png
deleted file mode 100644
index c60aad8..0000000
--- a/res/drawable-xhdpi/ic_bookmark_off_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_history_holo_dark.png b/res/drawable-xhdpi/ic_history_holo_dark.png
deleted file mode 100644
index c916bde..0000000
--- a/res/drawable-xhdpi/ic_history_holo_dark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_search_category_bookmark.png b/res/drawable-xhdpi/ic_search_category_bookmark.png
deleted file mode 100644
index 6046a95..0000000
--- a/res/drawable-xhdpi/ic_search_category_bookmark.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_search_category_history.png b/res/drawable-xhdpi/ic_search_category_history.png
deleted file mode 100644
index 681e4b4..0000000
--- a/res/drawable-xhdpi/ic_search_category_history.png
+++ /dev/null
Binary files differ
diff --git a/res/drawable-xhdpi/ic_search_category_suggest.png b/res/drawable-xhdpi/ic_search_category_suggest.png
deleted file mode 100644
index be0388c..0000000
--- a/res/drawable-xhdpi/ic_search_category_suggest.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-hdpi/ic_launcher_browser.png b/res/mipmap-hdpi/ic_launcher_browser.png
deleted file mode 100644
index 4f9377f..0000000
--- a/res/mipmap-hdpi/ic_launcher_browser.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-mdpi/ic_launcher_browser.png b/res/mipmap-mdpi/ic_launcher_browser.png
deleted file mode 100644
index 9bc6817..0000000
--- a/res/mipmap-mdpi/ic_launcher_browser.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xhdpi/ic_launcher_browser.png b/res/mipmap-xhdpi/ic_launcher_browser.png
deleted file mode 100644
index 9412fbe..0000000
--- a/res/mipmap-xhdpi/ic_launcher_browser.png
+++ /dev/null
Binary files differ
diff --git a/res/mipmap-xxhdpi/ic_launcher_browser.png b/res/mipmap-xxhdpi/ic_launcher_browser.png
deleted file mode 100644
index bd8c447..0000000
--- a/res/mipmap-xxhdpi/ic_launcher_browser.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_amazon.ico b/res/raw/favicon_amazon.ico
deleted file mode 100644
index 20a959c..0000000
--- a/res/raw/favicon_amazon.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_bbc.ico b/res/raw/favicon_bbc.ico
deleted file mode 100644
index 8f62b07..0000000
--- a/res/raw/favicon_bbc.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_cnn.ico b/res/raw/favicon_cnn.ico
deleted file mode 100644
index 4a8421d..0000000
--- a/res/raw/favicon_cnn.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_ebay.ico b/res/raw/favicon_ebay.ico
deleted file mode 100644
index d7c8a5e..0000000
--- a/res/raw/favicon_ebay.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_espn.ico b/res/raw/favicon_espn.ico
deleted file mode 100644
index 2dbe28a..0000000
--- a/res/raw/favicon_espn.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_facebook.ico b/res/raw/favicon_facebook.ico
deleted file mode 100644
index ea0c6a3..0000000
--- a/res/raw/favicon_facebook.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_google.ico b/res/raw/favicon_google.ico
deleted file mode 100644
index ee7c943..0000000
--- a/res/raw/favicon_google.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_msn.ico b/res/raw/favicon_msn.ico
deleted file mode 100644
index b2279f5..0000000
--- a/res/raw/favicon_msn.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_nytimes.ico b/res/raw/favicon_nytimes.ico
deleted file mode 100644
index fb4d000..0000000
--- a/res/raw/favicon_nytimes.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_picasa.ico b/res/raw/favicon_picasa.ico
deleted file mode 100644
index 22133b8..0000000
--- a/res/raw/favicon_picasa.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_twitter.ico b/res/raw/favicon_twitter.ico
deleted file mode 100644
index 00450d4..0000000
--- a/res/raw/favicon_twitter.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_weatherchannel.ico b/res/raw/favicon_weatherchannel.ico
deleted file mode 100644
index 5a56818..0000000
--- a/res/raw/favicon_weatherchannel.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_wikipedia.ico b/res/raw/favicon_wikipedia.ico
deleted file mode 100644
index 31b0e38..0000000
--- a/res/raw/favicon_wikipedia.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/favicon_yahoo.ico b/res/raw/favicon_yahoo.ico
deleted file mode 100644
index d7761e5..0000000
--- a/res/raw/favicon_yahoo.ico
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_amazon.png b/res/raw/thumb_amazon.png
deleted file mode 100644
index 4dd2f35..0000000
--- a/res/raw/thumb_amazon.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_bbc.png b/res/raw/thumb_bbc.png
deleted file mode 100644
index dff0424..0000000
--- a/res/raw/thumb_bbc.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_cnn.png b/res/raw/thumb_cnn.png
deleted file mode 100644
index 3d6fdc9..0000000
--- a/res/raw/thumb_cnn.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_ebay.png b/res/raw/thumb_ebay.png
deleted file mode 100644
index 023f678..0000000
--- a/res/raw/thumb_ebay.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_espn.png b/res/raw/thumb_espn.png
deleted file mode 100644
index c0882eb..0000000
--- a/res/raw/thumb_espn.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_facebook.png b/res/raw/thumb_facebook.png
deleted file mode 100644
index a8c047f..0000000
--- a/res/raw/thumb_facebook.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_google.png b/res/raw/thumb_google.png
deleted file mode 100644
index c54e6ea..0000000
--- a/res/raw/thumb_google.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_msn.png b/res/raw/thumb_msn.png
deleted file mode 100644
index 4ad710f..0000000
--- a/res/raw/thumb_msn.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_nytimes.png b/res/raw/thumb_nytimes.png
deleted file mode 100644
index d6849c3..0000000
--- a/res/raw/thumb_nytimes.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_picasa.png b/res/raw/thumb_picasa.png
deleted file mode 100644
index 5ec2d7a..0000000
--- a/res/raw/thumb_picasa.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_twitter.png b/res/raw/thumb_twitter.png
deleted file mode 100644
index 95e247f..0000000
--- a/res/raw/thumb_twitter.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_weatherchannel.png b/res/raw/thumb_weatherchannel.png
deleted file mode 100644
index a190a0c..0000000
--- a/res/raw/thumb_weatherchannel.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_wikipedia.png b/res/raw/thumb_wikipedia.png
deleted file mode 100644
index 7929468..0000000
--- a/res/raw/thumb_wikipedia.png
+++ /dev/null
Binary files differ
diff --git a/res/raw/thumb_yahoo.png b/res/raw/thumb_yahoo.png
deleted file mode 100644
index 08dd759..0000000
--- a/res/raw/thumb_yahoo.png
+++ /dev/null
Binary files differ
diff --git a/res/values/bookmarks_icons.xml b/res/values/bookmarks_icons.xml
deleted file mode 100644
index a22ce6c..0000000
--- a/res/values/bookmarks_icons.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2015 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.
--->
-
-<resources>
-    <array name="bookmark_preloads">
-        <item>@raw/favicon_google</item>
-        <item>@raw/thumb_google</item>
-        <item>@raw/favicon_picasa</item>
-        <item>@raw/thumb_picasa</item>
-        <item>@raw/favicon_yahoo</item>
-        <item>@raw/thumb_yahoo</item>
-        <item>@raw/favicon_msn</item>
-        <item>@raw/thumb_msn</item>
-        <item>@raw/favicon_twitter</item>
-        <item>@raw/thumb_twitter</item>
-        <item>@raw/favicon_facebook</item>
-        <item>@raw/thumb_facebook</item>
-        <item>@raw/favicon_wikipedia</item>
-        <item>@raw/thumb_wikipedia</item>
-        <item>@raw/favicon_ebay</item>
-        <item>@raw/thumb_ebay</item>
-        <item>@raw/favicon_cnn</item>
-        <item>@raw/thumb_cnn</item>
-        <item>@raw/favicon_nytimes</item>
-        <item>@raw/thumb_nytimes</item>
-        <item>@raw/favicon_espn</item>
-        <item>@raw/thumb_espn</item>
-        <item>@raw/favicon_amazon</item>
-        <item>@raw/thumb_amazon</item>
-        <item>@raw/favicon_weatherchannel</item>
-        <item>@raw/thumb_weatherchannel</item>
-        <item>@raw/favicon_bbc</item>
-        <item>@raw/thumb_bbc</item>
-    </array>
-</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index fa379b7..1a4d7b5 100644
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -18,43 +18,4 @@
     <!-- The name of the application. -->
     <string name="application_name">Bookmark Provider</string>
 
-    <!-- Bookmarks -->
-    <string-array name="bookmarks" translatable="false">
-        <item>Google</item>
-        <item>http://www.google.com/</item>
-        <item>Picasa</item>
-        <item>http://picasaweb.google.com/</item>
-        <item>Yahoo!</item>
-        <item>http://www.yahoo.com/</item>
-        <item>MSN</item>
-        <item>http://www.msn.com/</item>
-        <item>Twitter</item>
-        <item>http://twitter.com/</item>
-        <item>Facebook</item>
-        <item>http://www.facebook.com/</item>
-        <item>Wikipedia</item>
-        <item>http://www.wikipedia.org/</item>
-        <item>eBay</item>
-        <item>http://www.ebay.com/</item>
-        <item>CNN</item>
-        <item>http://www.cnn.com/</item>
-        <item>NY Times</item>
-        <item>http://www.nytimes.com/</item>
-        <item>ESPN</item>
-        <item>http://espn.com/</item>
-        <item>Amazon</item>
-        <item>http://www.amazon.com/</item>
-        <item>Weather Channel</item>
-        <item>http://www.weather.com/</item>
-        <item>BBC</item>
-        <item>http://www.bbc.co.uk/</item>
-    </string-array>
-
-    <!-- Bookmark name for Picasa website -->
-    <string name="picasa" translatable="false">Picasa</string>
-
-    <!-- The description of the suggestion that lets the user search the web for the query currently
-         in the text field. -->
-    <string name="search_the_web">Search the web</string>
-
 </resources>
diff --git a/src/com/android/bookmarkstore/BookmarkProvider.java b/src/com/android/bookmarkstore/BookmarkProvider.java
index 9f4f08f..12724c6 100644
--- a/src/com/android/bookmarkstore/BookmarkProvider.java
+++ b/src/com/android/bookmarkstore/BookmarkProvider.java
@@ -16,2131 +16,48 @@
 
 package com.android.bookmarkprovider;
 
-import android.accounts.Account;
-import android.accounts.AccountManager;
-import android.app.SearchManager;
-import android.content.ContentResolver;
-import android.content.ContentUris;
+import android.content.ContentProvider;
 import android.content.ContentValues;
-import android.content.Context;
-import android.content.Intent;
-import android.content.UriMatcher;
-import android.content.res.Resources;
-import android.content.res.TypedArray;
-import android.database.AbstractCursor;
 import android.database.Cursor;
-import android.database.DatabaseUtils;
 import android.database.MatrixCursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
-import android.provider.BaseColumns;
-import android.provider.Browser.BookmarkColumns;
 import android.provider.Browser;
-import android.provider.BrowserContract.Accounts;
-import android.provider.BrowserContract.Bookmarks;
-import android.provider.BrowserContract.ChromeSyncColumns;
-import android.provider.BrowserContract.Combined;
-import android.provider.BrowserContract.History;
-import android.provider.BrowserContract.Images;
-import android.provider.BrowserContract.Searches;
-import android.provider.BrowserContract.Settings;
-import android.provider.BrowserContract.SyncState;
 import android.provider.BrowserContract;
-import android.provider.ContactsContract.RawContacts;
-import android.provider.SyncStateContract;
-import android.text.TextUtils;
 
-import com.android.bookmarkprovider.R;
-import com.android.common.content.SyncStateContentProviderHelper;
-
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.List;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-public class BookmarkProvider extends SQLiteContentProvider {
-
-    public static final String PARAM_GROUP_BY = "groupBy";
-    public static final String PARAM_ALLOW_EMPTY_ACCOUNTS = "allowEmptyAccounts";
-
-    public static final String LEGACY_AUTHORITY = "browser";
-    static final Uri LEGACY_AUTHORITY_URI = new Uri.Builder()
-            .authority(LEGACY_AUTHORITY).scheme("content").build();
-
-    public static interface Thumbnails {
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(
-                BrowserContract.AUTHORITY_URI, "thumbnails");
-        public static final String _ID = "_id";
-        public static final String THUMBNAIL = "thumbnail";
-    }
-
-    public static interface OmniboxSuggestions {
-        public static final Uri CONTENT_URI = Uri.withAppendedPath(
-                BrowserContract.AUTHORITY_URI, "omnibox_suggestions");
-        public static final String _ID = "_id";
-        public static final String URL = "url";
-        public static final String TITLE = "title";
-        public static final String IS_BOOKMARK = "bookmark";
-    }
-
-    static final String TABLE_BOOKMARKS = "bookmarks";
-    static final String TABLE_HISTORY = "history";
-    static final String TABLE_IMAGES = "images";
-    static final String TABLE_SEARCHES = "searches";
-    static final String TABLE_SYNC_STATE = "syncstate";
-    static final String TABLE_SETTINGS = "settings";
-    static final String TABLE_SNAPSHOTS = "snapshots";
-    static final String TABLE_THUMBNAILS = "thumbnails";
-
-    static final String TABLE_BOOKMARKS_JOIN_IMAGES = "bookmarks LEFT OUTER JOIN images " +
-            "ON bookmarks.url = images." + Images.URL;
-    static final String TABLE_HISTORY_JOIN_IMAGES = "history LEFT OUTER JOIN images " +
-            "ON history.url = images." + Images.URL;
-
-    static final String VIEW_ACCOUNTS = "v_accounts";
-    static final String VIEW_SNAPSHOTS_COMBINED = "v_snapshots_combined";
-    static final String VIEW_OMNIBOX_SUGGESTIONS = "v_omnibox_suggestions";
-
-    static final String FORMAT_COMBINED_JOIN_SUBQUERY_JOIN_IMAGES =
-            "history LEFT OUTER JOIN (%s) bookmarks " +
-            "ON history.url = bookmarks.url LEFT OUTER JOIN images " +
-            "ON history.url = images.url_key";
-
-    static final String DEFAULT_SORT_HISTORY = History.DATE_LAST_VISITED + " DESC";
-    static final String DEFAULT_SORT_ACCOUNTS =
-            Accounts.ACCOUNT_NAME + " IS NOT NULL DESC, "
-            + Accounts.ACCOUNT_NAME + " ASC";
-
-    private static final String TABLE_BOOKMARKS_JOIN_HISTORY =
-        "history LEFT OUTER JOIN bookmarks ON history.url = bookmarks.url";
-
-    private static final String[] SUGGEST_PROJECTION = new String[] {
-            qualifyColumn(TABLE_HISTORY, History._ID),
-            qualifyColumn(TABLE_HISTORY, History.URL),
-            bookmarkOrHistoryColumn(Combined.TITLE),
-            bookmarkOrHistoryLiteral(Combined.URL,
-                    Integer.toString(R.drawable.ic_bookmark_off_holo_dark),
-                    Integer.toString(R.drawable.ic_history_holo_dark)),
-            qualifyColumn(TABLE_HISTORY, History.DATE_LAST_VISITED)};
-
-    private static final String SUGGEST_SELECTION =
-            "history.url LIKE ? OR history.url LIKE ? OR history.url LIKE ? OR history.url LIKE ?"
-            + " OR history.title LIKE ? OR bookmarks.title LIKE ?";
-
-    private static final String ZERO_QUERY_SUGGEST_SELECTION =
-            TABLE_HISTORY + "." + History.DATE_LAST_VISITED + " != 0";
-
-    private static final String IMAGE_PRUNE =
-            "url_key NOT IN (SELECT url FROM bookmarks " +
-            "WHERE url IS NOT NULL AND deleted == 0) AND url_key NOT IN " +
-            "(SELECT url FROM history WHERE url IS NOT NULL)";
-
-    // WHERE clause to find a deleted bookmark
-    private static final String DELETED_BOOKMARK_BY_ID =
-            Bookmarks._ID + "=? AND " + Bookmarks.IS_DELETED + "=1";
-
-    static final int THUMBNAILS = 10;
-    static final int THUMBNAILS_ID = 11;
-    static final int OMNIBOX_SUGGESTIONS = 20;
-
-    static final int BOOKMARKS = 1000;
-    static final int BOOKMARKS_ID = 1001;
-    static final int BOOKMARKS_FOLDER = 1002;
-    static final int BOOKMARKS_FOLDER_ID = 1003;
-    static final int BOOKMARKS_SUGGESTIONS = 1004;
-    static final int BOOKMARKS_DEFAULT_FOLDER_ID = 1005;
-
-    static final int HISTORY = 2000;
-    static final int HISTORY_ID = 2001;
-
-    static final int SEARCHES = 3000;
-    static final int SEARCHES_ID = 3001;
-
-    static final int SYNCSTATE = 4000;
-    static final int SYNCSTATE_ID = 4001;
-
-    static final int IMAGES = 5000;
-
-    static final int COMBINED = 6000;
-    static final int COMBINED_ID = 6001;
-
-    static final int ACCOUNTS = 7000;
-
-    static final int SETTINGS = 8000;
-
-    static final int LEGACY = 9000;
-    static final int LEGACY_ID = 9001;
-
-    public static final long FIXED_ID_ROOT = 1;
-
-    // Default sort order for unsync'd bookmarks
-    static final String DEFAULT_BOOKMARKS_SORT_ORDER =
-            Bookmarks.IS_FOLDER + " DESC, position ASC, _id ASC";
-
-    // Default sort order for sync'd bookmarks
-    static final String DEFAULT_BOOKMARKS_SORT_ORDER_SYNC = "position ASC, _id ASC";
-
-    static final UriMatcher URI_MATCHER = new UriMatcher(UriMatcher.NO_MATCH);
-
-    static final HashMap<String, String> ACCOUNTS_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> BOOKMARKS_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> OTHER_BOOKMARKS_PROJECTION_MAP =
-            new HashMap<String, String>();
-    static final HashMap<String, String> HISTORY_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> SYNC_STATE_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> IMAGES_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> COMBINED_HISTORY_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> COMBINED_BOOKMARK_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> SEARCHES_PROJECTION_MAP = new HashMap<String, String>();
-    static final HashMap<String, String> SETTINGS_PROJECTION_MAP = new HashMap<String, String>();
-
-    static {
-        final UriMatcher matcher = URI_MATCHER;
-        final String authority = BrowserContract.AUTHORITY;
-        matcher.addURI(authority, "accounts", ACCOUNTS);
-        matcher.addURI(authority, "bookmarks", BOOKMARKS);
-        matcher.addURI(authority, "bookmarks/#", BOOKMARKS_ID);
-        matcher.addURI(authority, "bookmarks/folder", BOOKMARKS_FOLDER);
-        matcher.addURI(authority, "bookmarks/folder/#", BOOKMARKS_FOLDER_ID);
-        matcher.addURI(authority, "bookmarks/folder/id", BOOKMARKS_DEFAULT_FOLDER_ID);
-        matcher.addURI(authority,
-                SearchManager.SUGGEST_URI_PATH_QUERY,
-                BOOKMARKS_SUGGESTIONS);
-        matcher.addURI(authority,
-                "bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY,
-                BOOKMARKS_SUGGESTIONS);
-        matcher.addURI(authority, "history", HISTORY);
-        matcher.addURI(authority, "history/#", HISTORY_ID);
-        matcher.addURI(authority, "searches", SEARCHES);
-        matcher.addURI(authority, "searches/#", SEARCHES_ID);
-        matcher.addURI(authority, "syncstate", SYNCSTATE);
-        matcher.addURI(authority, "syncstate/#", SYNCSTATE_ID);
-        matcher.addURI(authority, "images", IMAGES);
-        matcher.addURI(authority, "combined", COMBINED);
-        matcher.addURI(authority, "combined/#", COMBINED_ID);
-        matcher.addURI(authority, "settings", SETTINGS);
-        matcher.addURI(authority, "thumbnails", THUMBNAILS);
-        matcher.addURI(authority, "thumbnails/#", THUMBNAILS_ID);
-        matcher.addURI(authority, "omnibox_suggestions", OMNIBOX_SUGGESTIONS);
-
-        // Legacy
-        matcher.addURI(LEGACY_AUTHORITY, "searches", SEARCHES);
-        matcher.addURI(LEGACY_AUTHORITY, "searches/#", SEARCHES_ID);
-        matcher.addURI(LEGACY_AUTHORITY, "bookmarks", LEGACY);
-        matcher.addURI(LEGACY_AUTHORITY, "bookmarks/#", LEGACY_ID);
-        matcher.addURI(LEGACY_AUTHORITY,
-                SearchManager.SUGGEST_URI_PATH_QUERY,
-                BOOKMARKS_SUGGESTIONS);
-        matcher.addURI(LEGACY_AUTHORITY,
-                "bookmarks/" + SearchManager.SUGGEST_URI_PATH_QUERY,
-                BOOKMARKS_SUGGESTIONS);
-
-        // Projection maps
-        HashMap<String, String> map;
-
-        // Accounts
-        map = ACCOUNTS_PROJECTION_MAP;
-        map.put(Accounts.ACCOUNT_TYPE, Accounts.ACCOUNT_TYPE);
-        map.put(Accounts.ACCOUNT_NAME, Accounts.ACCOUNT_NAME);
-        map.put(Accounts.ROOT_ID, Accounts.ROOT_ID);
-
-        // Bookmarks
-        map = BOOKMARKS_PROJECTION_MAP;
-        map.put(Bookmarks._ID, qualifyColumn(TABLE_BOOKMARKS, Bookmarks._ID));
-        map.put(Bookmarks.TITLE, Bookmarks.TITLE);
-        map.put(Bookmarks.URL, Bookmarks.URL);
-        map.put(Bookmarks.FAVICON, Bookmarks.FAVICON);
-        map.put(Bookmarks.THUMBNAIL, Bookmarks.THUMBNAIL);
-        map.put(Bookmarks.TOUCH_ICON, Bookmarks.TOUCH_ICON);
-        map.put(Bookmarks.IS_FOLDER, Bookmarks.IS_FOLDER);
-        map.put(Bookmarks.PARENT, Bookmarks.PARENT);
-        map.put(Bookmarks.POSITION, Bookmarks.POSITION);
-        map.put(Bookmarks.INSERT_AFTER, Bookmarks.INSERT_AFTER);
-        map.put(Bookmarks.IS_DELETED, Bookmarks.IS_DELETED);
-        map.put(Bookmarks.ACCOUNT_NAME, Bookmarks.ACCOUNT_NAME);
-        map.put(Bookmarks.ACCOUNT_TYPE, Bookmarks.ACCOUNT_TYPE);
-        map.put(Bookmarks.SOURCE_ID, Bookmarks.SOURCE_ID);
-        map.put(Bookmarks.VERSION, Bookmarks.VERSION);
-        map.put(Bookmarks.DATE_CREATED, Bookmarks.DATE_CREATED);
-        map.put(Bookmarks.DATE_MODIFIED, Bookmarks.DATE_MODIFIED);
-        map.put(Bookmarks.DIRTY, Bookmarks.DIRTY);
-        map.put(Bookmarks.SYNC1, Bookmarks.SYNC1);
-        map.put(Bookmarks.SYNC2, Bookmarks.SYNC2);
-        map.put(Bookmarks.SYNC3, Bookmarks.SYNC3);
-        map.put(Bookmarks.SYNC4, Bookmarks.SYNC4);
-        map.put(Bookmarks.SYNC5, Bookmarks.SYNC5);
-        map.put(Bookmarks.PARENT_SOURCE_ID, "(SELECT " + Bookmarks.SOURCE_ID +
-                " FROM " + TABLE_BOOKMARKS + " A WHERE " +
-                "A." + Bookmarks._ID + "=" + TABLE_BOOKMARKS + "." + Bookmarks.PARENT +
-                ") AS " + Bookmarks.PARENT_SOURCE_ID);
-        map.put(Bookmarks.INSERT_AFTER_SOURCE_ID, "(SELECT " + Bookmarks.SOURCE_ID +
-                " FROM " + TABLE_BOOKMARKS + " A WHERE " +
-                "A." + Bookmarks._ID + "=" + TABLE_BOOKMARKS + "." + Bookmarks.INSERT_AFTER +
-                ") AS " + Bookmarks.INSERT_AFTER_SOURCE_ID);
-        map.put(Bookmarks.TYPE, "CASE "
-                + " WHEN " + Bookmarks.IS_FOLDER + "=0 THEN "
-                    + Bookmarks.BOOKMARK_TYPE_BOOKMARK
-                + " WHEN " + ChromeSyncColumns.SERVER_UNIQUE + "='"
-                    + ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR + "' THEN "
-                    + Bookmarks.BOOKMARK_TYPE_BOOKMARK_BAR_FOLDER
-                + " WHEN " + ChromeSyncColumns.SERVER_UNIQUE + "='"
-                    + ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS + "' THEN "
-                    + Bookmarks.BOOKMARK_TYPE_OTHER_FOLDER
-                + " ELSE " + Bookmarks.BOOKMARK_TYPE_FOLDER
-                + " END AS " + Bookmarks.TYPE);
-
-        // Other bookmarks
-        OTHER_BOOKMARKS_PROJECTION_MAP.putAll(BOOKMARKS_PROJECTION_MAP);
-        OTHER_BOOKMARKS_PROJECTION_MAP.put(Bookmarks.POSITION,
-                Long.toString(Long.MAX_VALUE) + " AS " + Bookmarks.POSITION);
-
-        // History
-        map = HISTORY_PROJECTION_MAP;
-        map.put(History._ID, qualifyColumn(TABLE_HISTORY, History._ID));
-        map.put(History.TITLE, History.TITLE);
-        map.put(History.URL, History.URL);
-        map.put(History.FAVICON, History.FAVICON);
-        map.put(History.THUMBNAIL, History.THUMBNAIL);
-        map.put(History.TOUCH_ICON, History.TOUCH_ICON);
-        map.put(History.DATE_CREATED, History.DATE_CREATED);
-        map.put(History.DATE_LAST_VISITED, History.DATE_LAST_VISITED);
-        map.put(History.VISITS, History.VISITS);
-        map.put(History.USER_ENTERED, History.USER_ENTERED);
-
-        // Sync state
-        map = SYNC_STATE_PROJECTION_MAP;
-        map.put(SyncState._ID, SyncState._ID);
-        map.put(SyncState.ACCOUNT_NAME, SyncState.ACCOUNT_NAME);
-        map.put(SyncState.ACCOUNT_TYPE, SyncState.ACCOUNT_TYPE);
-        map.put(SyncState.DATA, SyncState.DATA);
-
-        // Images
-        map = IMAGES_PROJECTION_MAP;
-        map.put(Images.URL, Images.URL);
-        map.put(Images.FAVICON, Images.FAVICON);
-        map.put(Images.THUMBNAIL, Images.THUMBNAIL);
-        map.put(Images.TOUCH_ICON, Images.TOUCH_ICON);
-
-        // Combined history half
-        map = COMBINED_HISTORY_PROJECTION_MAP;
-        map.put(Combined._ID, bookmarkOrHistoryColumn(Combined._ID));
-        map.put(Combined.TITLE, bookmarkOrHistoryColumn(Combined.TITLE));
-        map.put(Combined.URL, qualifyColumn(TABLE_HISTORY, Combined.URL));
-        map.put(Combined.DATE_CREATED, qualifyColumn(TABLE_HISTORY, Combined.DATE_CREATED));
-        map.put(Combined.DATE_LAST_VISITED, Combined.DATE_LAST_VISITED);
-        map.put(Combined.IS_BOOKMARK, "CASE WHEN " +
-                TABLE_BOOKMARKS + "." + Bookmarks._ID +
-                " IS NOT NULL THEN 1 ELSE 0 END AS " + Combined.IS_BOOKMARK);
-        map.put(Combined.VISITS, Combined.VISITS);
-        map.put(Combined.FAVICON, Combined.FAVICON);
-        map.put(Combined.THUMBNAIL, Combined.THUMBNAIL);
-        map.put(Combined.TOUCH_ICON, Combined.TOUCH_ICON);
-        map.put(Combined.USER_ENTERED, "NULL AS " + Combined.USER_ENTERED);
-
-        // Combined bookmark half
-        map = COMBINED_BOOKMARK_PROJECTION_MAP;
-        map.put(Combined._ID, Combined._ID);
-        map.put(Combined.TITLE, Combined.TITLE);
-        map.put(Combined.URL, Combined.URL);
-        map.put(Combined.DATE_CREATED, Combined.DATE_CREATED);
-        map.put(Combined.DATE_LAST_VISITED, "NULL AS " + Combined.DATE_LAST_VISITED);
-        map.put(Combined.IS_BOOKMARK, "1 AS " + Combined.IS_BOOKMARK);
-        map.put(Combined.VISITS, "0 AS " + Combined.VISITS);
-        map.put(Combined.FAVICON, Combined.FAVICON);
-        map.put(Combined.THUMBNAIL, Combined.THUMBNAIL);
-        map.put(Combined.TOUCH_ICON, Combined.TOUCH_ICON);
-        map.put(Combined.USER_ENTERED, "NULL AS " + Combined.USER_ENTERED);
-
-        // Searches
-        map = SEARCHES_PROJECTION_MAP;
-        map.put(Searches._ID, Searches._ID);
-        map.put(Searches.SEARCH, Searches.SEARCH);
-        map.put(Searches.DATE, Searches.DATE);
-
-        // Settings
-        map = SETTINGS_PROJECTION_MAP;
-        map.put(Settings.KEY, Settings.KEY);
-        map.put(Settings.VALUE, Settings.VALUE);
-    }
-
-    static final String bookmarkOrHistoryColumn(String column) {
-        return "CASE WHEN bookmarks." + column + " IS NOT NULL THEN " +
-                "bookmarks." + column + " ELSE history." + column + " END AS " + column;
-    }
-
-    static final String bookmarkOrHistoryLiteral(String column, String bookmarkValue,
-            String historyValue) {
-        return "CASE WHEN bookmarks." + column + " IS NOT NULL THEN \"" + bookmarkValue +
-                "\" ELSE \"" + historyValue + "\" END";
-    }
-
-    static final String qualifyColumn(String table, String column) {
-        return table + "." + column + " AS " + column;
-    }
-
-    DatabaseHelper mOpenHelper;
-    SyncStateContentProviderHelper mSyncHelper = new SyncStateContentProviderHelper();
-
-    final class DatabaseHelper extends SQLiteOpenHelper {
-        static final String DATABASE_NAME = "browser2.db";
-        static final int DATABASE_VERSION = 32;
-        public DatabaseHelper(Context context) {
-            super(context, DATABASE_NAME, null, DATABASE_VERSION);
-            setWriteAheadLoggingEnabled(true);
-        }
-
-        @Override
-        public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + TABLE_BOOKMARKS + "(" +
-                    Bookmarks._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    Bookmarks.TITLE + " TEXT," +
-                    Bookmarks.URL + " TEXT," +
-                    Bookmarks.IS_FOLDER + " INTEGER NOT NULL DEFAULT 0," +
-                    Bookmarks.PARENT + " INTEGER," +
-                    Bookmarks.POSITION + " INTEGER NOT NULL," +
-                    Bookmarks.INSERT_AFTER + " INTEGER," +
-                    Bookmarks.IS_DELETED + " INTEGER NOT NULL DEFAULT 0," +
-                    Bookmarks.ACCOUNT_NAME + " TEXT," +
-                    Bookmarks.ACCOUNT_TYPE + " TEXT," +
-                    Bookmarks.SOURCE_ID + " TEXT," +
-                    Bookmarks.VERSION + " INTEGER NOT NULL DEFAULT 1," +
-                    Bookmarks.DATE_CREATED + " INTEGER," +
-                    Bookmarks.DATE_MODIFIED + " INTEGER," +
-                    Bookmarks.DIRTY + " INTEGER NOT NULL DEFAULT 0," +
-                    Bookmarks.SYNC1 + " TEXT," +
-                    Bookmarks.SYNC2 + " TEXT," +
-                    Bookmarks.SYNC3 + " TEXT," +
-                    Bookmarks.SYNC4 + " TEXT," +
-                    Bookmarks.SYNC5 + " TEXT" +
-                    ");");
-
-            // TODO indices
-
-            db.execSQL("CREATE TABLE " + TABLE_HISTORY + "(" +
-                    History._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    History.TITLE + " TEXT," +
-                    History.URL + " TEXT NOT NULL," +
-                    History.DATE_CREATED + " INTEGER," +
-                    History.DATE_LAST_VISITED + " INTEGER," +
-                    History.VISITS + " INTEGER NOT NULL DEFAULT 0," +
-                    History.USER_ENTERED + " INTEGER" +
-                    ");");
-
-            db.execSQL("CREATE TABLE " + TABLE_IMAGES + " (" +
-                    Images.URL + " TEXT UNIQUE NOT NULL," +
-                    Images.FAVICON + " BLOB," +
-                    Images.THUMBNAIL + " BLOB," +
-                    Images.TOUCH_ICON + " BLOB" +
-                    ");");
-            db.execSQL("CREATE INDEX imagesUrlIndex ON " + TABLE_IMAGES +
-                    "(" + Images.URL + ")");
-
-            db.execSQL("CREATE TABLE " + TABLE_SEARCHES + " (" +
-                    Searches._ID + " INTEGER PRIMARY KEY AUTOINCREMENT," +
-                    Searches.SEARCH + " TEXT," +
-                    Searches.DATE + " LONG" +
-                    ");");
-
-            db.execSQL("CREATE TABLE " + TABLE_SETTINGS + " (" +
-                    Settings.KEY + " TEXT PRIMARY KEY," +
-                    Settings.VALUE + " TEXT NOT NULL" +
-                    ");");
-
-            createAccountsView(db);
-            createThumbnails(db);
-
-            mSyncHelper.createDatabase(db);
-
-            createDefaultBookmarks(db);
-
-            enableSync(db);
-            createOmniboxSuggestions(db);
-        }
-
-        void createOmniboxSuggestions(SQLiteDatabase db) {
-            db.execSQL(SQL_CREATE_VIEW_OMNIBOX_SUGGESTIONS);
-        }
-
-        void createThumbnails(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE IF NOT EXISTS " + TABLE_THUMBNAILS + " (" +
-                    Thumbnails._ID + " INTEGER PRIMARY KEY," +
-                    Thumbnails.THUMBNAIL + " BLOB NOT NULL" +
-                    ");");
-        }
-
-        void enableSync(SQLiteDatabase db) {
-            ContentValues values = new ContentValues();
-            values.put(Settings.KEY, Settings.KEY_SYNC_ENABLED);
-            values.put(Settings.VALUE, 1);
-            insertSettingsInTransaction(db, values);
-            // Enable bookmark sync on all accounts
-            AccountManager am = (AccountManager) getContext().getSystemService(
-                    Context.ACCOUNT_SERVICE);
-            if (am == null) {
-                return;
-            }
-            Account[] accounts = am.getAccountsByType("com.google");
-            if (accounts == null || accounts.length == 0) {
-                return;
-            }
-            for (Account account : accounts) {
-                if (ContentResolver.getIsSyncable(
-                        account, BrowserContract.AUTHORITY) == 0) {
-                    // Account wasn't syncable, enable it
-                    ContentResolver.setIsSyncable(
-                            account, BrowserContract.AUTHORITY, 1);
-                    ContentResolver.setSyncAutomatically(
-                            account, BrowserContract.AUTHORITY, true);
-                }
-            }
-        }
-
-        void createAccountsView(SQLiteDatabase db) {
-            db.execSQL("CREATE VIEW IF NOT EXISTS v_accounts AS "
-                    + "SELECT NULL AS " + Accounts.ACCOUNT_NAME
-                    + ", NULL AS " + Accounts.ACCOUNT_TYPE
-                    + ", " + FIXED_ID_ROOT + " AS " + Accounts.ROOT_ID
-                    + " UNION ALL SELECT " + Accounts.ACCOUNT_NAME
-                    + ", " + Accounts.ACCOUNT_TYPE + ", "
-                    + Bookmarks._ID + " AS " + Accounts.ROOT_ID
-                    + " FROM " + TABLE_BOOKMARKS + " WHERE "
-                    + ChromeSyncColumns.SERVER_UNIQUE + " = \""
-                    + ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR + "\" AND "
-                    + Bookmarks.IS_DELETED + " = 0");
-        }
-
-        @Override
-        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-        }
-
-        public void onOpen(SQLiteDatabase db) {
-            mSyncHelper.onDatabaseOpened(db);
-        }
-
-        private void createDefaultBookmarks(SQLiteDatabase db) {
-            ContentValues values = new ContentValues();
-            // TODO figure out how to deal with localization for the defaults
-
-            // Bookmarks folder
-            values.put(Bookmarks._ID, FIXED_ID_ROOT);
-            values.put(ChromeSyncColumns.SERVER_UNIQUE, ChromeSyncColumns.FOLDER_NAME_BOOKMARKS);
-            values.put(Bookmarks.TITLE, "Bookmarks");
-            values.putNull(Bookmarks.PARENT);
-            values.put(Bookmarks.POSITION, 0);
-            values.put(Bookmarks.IS_FOLDER, true);
-            values.put(Bookmarks.DIRTY, true);
-            db.insertOrThrow(TABLE_BOOKMARKS, null, values);
-
-            addDefaultBookmarks(db, FIXED_ID_ROOT);
-        }
-
-        private void addDefaultBookmarks(SQLiteDatabase db, long parentId) {
-            Resources res = getContext().getResources();
-            final CharSequence[] bookmarks = res.getTextArray(
-                    R.array.bookmarks);
-            int size = bookmarks.length;
-            TypedArray preloads = res.obtainTypedArray(R.array.bookmark_preloads);
-            try {
-                String parent = Long.toString(parentId);
-                String now = Long.toString(System.currentTimeMillis());
-                for (int i = 0; i < size; i = i + 2) {
-                    CharSequence bookmarkDestination = replaceSystemPropertyInString(getContext(),
-                            bookmarks[i + 1]);
-                    db.execSQL("INSERT INTO bookmarks (" +
-                            Bookmarks.TITLE + ", " +
-                            Bookmarks.URL + ", " +
-                            Bookmarks.IS_FOLDER + "," +
-                            Bookmarks.PARENT + "," +
-                            Bookmarks.POSITION + "," +
-                            Bookmarks.DATE_CREATED +
-                        ") VALUES (" +
-                            "'" + bookmarks[i] + "', " +
-                            "'" + bookmarkDestination + "', " +
-                            "0," +
-                            parent + "," +
-                            Integer.toString(i) + "," +
-                            now +
-                            ");");
-
-                    int faviconId = preloads.getResourceId(i, 0);
-                    int thumbId = preloads.getResourceId(i + 1, 0);
-                    byte[] thumb = null, favicon = null;
-                    try {
-                        thumb = readRaw(res, thumbId);
-                    } catch (IOException e) {
-                    }
-                    try {
-                        favicon = readRaw(res, faviconId);
-                    } catch (IOException e) {
-                    }
-                    if (thumb != null || favicon != null) {
-                        ContentValues imageValues = new ContentValues();
-                        imageValues.put(Images.URL, bookmarkDestination.toString());
-                        if (favicon != null) {
-                            imageValues.put(Images.FAVICON, favicon);
-                        }
-                        if (thumb != null) {
-                            imageValues.put(Images.THUMBNAIL, thumb);
-                        }
-                        db.insert(TABLE_IMAGES, Images.FAVICON, imageValues);
-                    }
-                }
-            } catch (ArrayIndexOutOfBoundsException e) {
-            } finally {
-                preloads.recycle();
-            }
-        }
-
-        private byte[] readRaw(Resources res, int id) throws IOException {
-            if (id == 0) {
-                return null;
-            }
-            InputStream is = res.openRawResource(id);
-            try {
-                ByteArrayOutputStream bos = new ByteArrayOutputStream();
-                byte[] buf = new byte[4096];
-                int read;
-                while ((read = is.read(buf)) > 0) {
-                    bos.write(buf, 0, read);
-                }
-                bos.flush();
-                return bos.toByteArray();
-            } finally {
-                is.close();
-            }
-        }
-
-        // XXX: This is a major hack to remove our dependency on gsf constants and
-        // its content provider. http://b/issue?id=2425179
-        private String getClientId(ContentResolver cr) {
-            String ret = "android-google";
-            Cursor c = null;
-            try {
-                c = cr.query(Uri.parse("content://com.google.settings/partner"),
-                        new String[] { "value" }, "name='client_id'", null, null);
-                if (c != null && c.moveToNext()) {
-                    ret = c.getString(0);
-                }
-            } catch (RuntimeException ex) {
-                // fall through to return the default
-            } finally {
-                if (c != null) {
-                    c.close();
-                }
-            }
-            return ret;
-        }
-
-        private CharSequence replaceSystemPropertyInString(Context context, CharSequence srcString) {
-            StringBuffer sb = new StringBuffer();
-            int lastCharLoc = 0;
-
-            final String client_id = getClientId(context.getContentResolver());
-
-            for (int i = 0; i < srcString.length(); ++i) {
-                char c = srcString.charAt(i);
-                if (c == '{') {
-                    sb.append(srcString.subSequence(lastCharLoc, i));
-                    lastCharLoc = i;
-              inner:
-                    for (int j = i; j < srcString.length(); ++j) {
-                        char k = srcString.charAt(j);
-                        if (k == '}') {
-                            String propertyKeyValue = srcString.subSequence(i + 1, j).toString();
-                            if (propertyKeyValue.equals("CLIENT_ID")) {
-                                sb.append(client_id);
-                            } else {
-                                sb.append("unknown");
-                            }
-                            lastCharLoc = j + 1;
-                            i = j;
-                            break inner;
-                        }
-                    }
-                }
-            }
-            if (srcString.length() - lastCharLoc > 0) {
-                // Put on the tail, if there is one
-                sb.append(srcString.subSequence(lastCharLoc, srcString.length()));
-            }
-            return sb;
-        }
-    }
+/**
+ * This class exists only for compatibility reasons to prevent apps
+ * querying it from getting null cursors they do not expect and crash.
+ */
+public class BookmarkProvider extends ContentProvider {
 
     @Override
-    public SQLiteOpenHelper getDatabaseHelper(Context context) {
-        synchronized (this) {
-            if (mOpenHelper == null) {
-                mOpenHelper = new DatabaseHelper(context);
-            }
-            return mOpenHelper;
-        }
-    }
-
-    @Override
-    public boolean isCallerSyncAdapter(Uri uri) {
-        return uri.getBooleanQueryParameter(BrowserContract.CALLER_IS_SYNCADAPTER, false);
+    public boolean onCreate() {
+        return true;
     }
 
     @Override
     public String getType(Uri uri) {
-        final int match = URI_MATCHER.match(uri);
-        switch (match) {
-            case LEGACY:
-            case BOOKMARKS:
-                return Bookmarks.CONTENT_TYPE;
-            case LEGACY_ID:
-            case BOOKMARKS_ID:
-                return Bookmarks.CONTENT_ITEM_TYPE;
-            case HISTORY:
-                return History.CONTENT_TYPE;
-            case HISTORY_ID:
-                return History.CONTENT_ITEM_TYPE;
-            case SEARCHES:
-                return Searches.CONTENT_TYPE;
-            case SEARCHES_ID:
-                return Searches.CONTENT_ITEM_TYPE;
-        }
+        return BrowserContract.Bookmarks.CONTENT_TYPE;
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues values) {
         return null;
     }
 
-    boolean isNullAccount(String account) {
-        if (account == null) return true;
-        account = account.trim();
-        return account.length() == 0 || account.equals("null");
+    @Override
+    public int delete(Uri uri, String selection, String[] selectionArgs) {
+        return 0;
     }
 
-    Object[] getSelectionWithAccounts(Uri uri, String selection, String[] selectionArgs) {
-        // Look for account info
-        String accountType = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE);
-        String accountName = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME);
-        boolean hasAccounts = false;
-        if (accountType != null && accountName != null) {
-            if (!isNullAccount(accountType) && !isNullAccount(accountName)) {
-                selection = DatabaseUtils.concatenateWhere(selection,
-                        Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=? ");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { accountType, accountName });
-                hasAccounts = true;
-            } else {
-                selection = DatabaseUtils.concatenateWhere(selection,
-                        Bookmarks.ACCOUNT_NAME + " IS NULL AND " +
-                        Bookmarks.ACCOUNT_TYPE + " IS NULL");
-            }
-        }
-        return new Object[] { selection, selectionArgs, hasAccounts };
+    @Override
+    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
+        return 0;
     }
 
     @Override
     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
             String sortOrder) {
-        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        final int match = URI_MATCHER.match(uri);
-        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-        String limit = uri.getQueryParameter(BrowserContract.PARAM_LIMIT);
-        String groupBy = uri.getQueryParameter(PARAM_GROUP_BY);
-        switch (match) {
-            case ACCOUNTS: {
-                qb.setTables(VIEW_ACCOUNTS);
-                qb.setProjectionMap(ACCOUNTS_PROJECTION_MAP);
-                String allowEmpty = uri.getQueryParameter(PARAM_ALLOW_EMPTY_ACCOUNTS);
-                if ("false".equals(allowEmpty)) {
-                    selection = DatabaseUtils.concatenateWhere(selection,
-                            SQL_WHERE_ACCOUNT_HAS_BOOKMARKS);
-                }
-                if (sortOrder == null) {
-                    sortOrder = DEFAULT_SORT_ACCOUNTS;
-                }
-                break;
-            }
-
-            case BOOKMARKS_FOLDER_ID:
-            case BOOKMARKS_ID:
-            case BOOKMARKS: {
-                // Only show deleted bookmarks if requested to do so
-                if (!uri.getBooleanQueryParameter(Bookmarks.QUERY_PARAMETER_SHOW_DELETED, false)) {
-                    selection = DatabaseUtils.concatenateWhere(
-                            Bookmarks.IS_DELETED + "=0", selection);
-                }
-
-                if (match == BOOKMARKS_ID) {
-                    // Tack on the ID of the specific bookmark requested
-                    selection = DatabaseUtils.concatenateWhere(selection,
-                            TABLE_BOOKMARKS + "." + Bookmarks._ID + "=?");
-                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                            new String[] { Long.toString(ContentUris.parseId(uri)) });
-                } else if (match == BOOKMARKS_FOLDER_ID) {
-                    // Tack on the ID of the specific folder requested
-                    selection = DatabaseUtils.concatenateWhere(selection,
-                            TABLE_BOOKMARKS + "." + Bookmarks.PARENT + "=?");
-                    selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                            new String[] { Long.toString(ContentUris.parseId(uri)) });
-                }
-
-                Object[] withAccount = getSelectionWithAccounts(uri, selection, selectionArgs);
-                selection = (String) withAccount[0];
-                selectionArgs = (String[]) withAccount[1];
-                boolean hasAccounts = (Boolean) withAccount[2];
-
-                // Set a default sort order if one isn't specified
-                if (TextUtils.isEmpty(sortOrder)) {
-                    if (hasAccounts) {
-                        sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER_SYNC;
-                    } else {
-                        sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
-                    }
-                }
-
-                qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
-                qb.setTables(TABLE_BOOKMARKS_JOIN_IMAGES);
-                break;
-            }
-
-            case BOOKMARKS_FOLDER: {
-                // Look for an account
-                boolean useAccount = false;
-                String accountType = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE);
-                String accountName = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME);
-                if (!isNullAccount(accountType) && !isNullAccount(accountName)) {
-                    useAccount = true;
-                }
-
-                qb.setTables(TABLE_BOOKMARKS_JOIN_IMAGES);
-                String[] args;
-                String query;
-                // Set a default sort order if one isn't specified
-                if (TextUtils.isEmpty(sortOrder)) {
-                    if (useAccount) {
-                        sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER_SYNC;
-                    } else {
-                        sortOrder = DEFAULT_BOOKMARKS_SORT_ORDER;
-                    }
-                }
-                if (!useAccount) {
-                    qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
-                    String where = Bookmarks.PARENT + "=? AND " + Bookmarks.IS_DELETED + "=0";
-                    where = DatabaseUtils.concatenateWhere(where, selection);
-                    args = new String[] { Long.toString(FIXED_ID_ROOT) };
-                    if (selectionArgs != null) {
-                        args = DatabaseUtils.appendSelectionArgs(args, selectionArgs);
-                    }
-                    query = qb.buildQuery(projection, where, null, null, sortOrder, null);
-                } else {
-                    qb.setProjectionMap(BOOKMARKS_PROJECTION_MAP);
-                    String where = Bookmarks.ACCOUNT_TYPE + "=? AND " +
-                            Bookmarks.ACCOUNT_NAME + "=? " +
-                            "AND parent = " +
-                            "(SELECT _id FROM " + TABLE_BOOKMARKS + " WHERE " +
-                            ChromeSyncColumns.SERVER_UNIQUE + "=" +
-                            "'" + ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR + "' " +
-                            "AND account_type = ? AND account_name = ?) " +
-                            "AND " + Bookmarks.IS_DELETED + "=0";
-                    where = DatabaseUtils.concatenateWhere(where, selection);
-                    String bookmarksBarQuery = qb.buildQuery(projection,
-                            where, null, null, null, null);
-                    args = new String[] {accountType, accountName,
-                            accountType, accountName};
-                    if (selectionArgs != null) {
-                        args = DatabaseUtils.appendSelectionArgs(args, selectionArgs);
-                    }
-
-                    where = Bookmarks.ACCOUNT_TYPE + "=? AND " + Bookmarks.ACCOUNT_NAME + "=?" +
-                            " AND " + ChromeSyncColumns.SERVER_UNIQUE + "=?";
-                    where = DatabaseUtils.concatenateWhere(where, selection);
-                    qb.setProjectionMap(OTHER_BOOKMARKS_PROJECTION_MAP);
-                    String otherBookmarksQuery = qb.buildQuery(projection,
-                            where, null, null, null, null);
-
-                    query = qb.buildUnionQuery(
-                            new String[] { bookmarksBarQuery, otherBookmarksQuery },
-                            sortOrder, limit);
-
-                    args = DatabaseUtils.appendSelectionArgs(args, new String[] {
-                            accountType, accountName, ChromeSyncColumns.FOLDER_NAME_OTHER_BOOKMARKS,
-                            });
-                    if (selectionArgs != null) {
-                        args = DatabaseUtils.appendSelectionArgs(args, selectionArgs);
-                    }
-                }
-
-                Cursor cursor = db.rawQuery(query, args);
-                if (cursor != null) {
-                    cursor.setNotificationUri(getContext().getContentResolver(),
-                            BrowserContract.AUTHORITY_URI);
-                }
-                return cursor;
-            }
-
-            case BOOKMARKS_DEFAULT_FOLDER_ID: {
-                String accountName = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_NAME);
-                String accountType = uri.getQueryParameter(Bookmarks.PARAM_ACCOUNT_TYPE);
-                long id = queryDefaultFolderId(accountName, accountType);
-                MatrixCursor c = new MatrixCursor(new String[] {Bookmarks._ID});
-                c.newRow().add(id);
-                return c;
-            }
-
-            case BOOKMARKS_SUGGESTIONS: {
-                return doSuggestQuery(selection, selectionArgs, limit);
-            }
-
-            case HISTORY_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case HISTORY: {
-                filterSearchClient(selectionArgs);
-                if (sortOrder == null) {
-                    sortOrder = DEFAULT_SORT_HISTORY;
-                }
-                qb.setProjectionMap(HISTORY_PROJECTION_MAP);
-                qb.setTables(TABLE_HISTORY_JOIN_IMAGES);
-                break;
-            }
-
-            case SEARCHES_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection, TABLE_SEARCHES + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case SEARCHES: {
-                qb.setTables(TABLE_SEARCHES);
-                qb.setProjectionMap(SEARCHES_PROJECTION_MAP);
-                break;
-            }
-
-            case SYNCSTATE: {
-                return mSyncHelper.query(db, projection, selection, selectionArgs, sortOrder);
-            }
-
-            case SYNCSTATE_ID: {
-                selection = appendAccountToSelection(uri, selection);
-                String selectionWithId =
-                        (SyncStateContract.Columns._ID + "=" + ContentUris.parseId(uri) + " ")
-                        + (selection == null ? "" : " AND (" + selection + ")");
-                return mSyncHelper.query(db, projection, selectionWithId, selectionArgs, sortOrder);
-            }
-
-            case IMAGES: {
-                qb.setTables(TABLE_IMAGES);
-                qb.setProjectionMap(IMAGES_PROJECTION_MAP);
-                break;
-            }
-
-            case LEGACY_ID:
-            case COMBINED_ID: {
-                selection = DatabaseUtils.concatenateWhere(
-                        selection, Combined._ID + " = CAST(? AS INTEGER)");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case LEGACY:
-            case COMBINED: {
-                if ((match == LEGACY || match == LEGACY_ID)
-                        && projection == null) {
-                    projection = Browser.HISTORY_PROJECTION;
-                }
-                String[] args = createCombinedQuery(uri, projection, qb);
-                if (selectionArgs == null) {
-                    selectionArgs = args;
-                } else {
-                    selectionArgs = DatabaseUtils.appendSelectionArgs(args, selectionArgs);
-                }
-                break;
-            }
-
-            case SETTINGS: {
-                qb.setTables(TABLE_SETTINGS);
-                qb.setProjectionMap(SETTINGS_PROJECTION_MAP);
-                break;
-            }
-
-            case THUMBNAILS_ID: {
-                selection = DatabaseUtils.concatenateWhere(
-                        selection, Thumbnails._ID + " = ?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case THUMBNAILS: {
-                qb.setTables(TABLE_THUMBNAILS);
-                break;
-            }
-
-            case OMNIBOX_SUGGESTIONS: {
-                qb.setTables(VIEW_OMNIBOX_SUGGESTIONS);
-                break;
-            }
-
-            default: {
-                throw new UnsupportedOperationException("Unknown URL " + uri.toString());
-            }
-        }
-
-        Cursor cursor = qb.query(db, projection, selection, selectionArgs, groupBy,
-                null, sortOrder, limit);
-        cursor.setNotificationUri(getContext().getContentResolver(), BrowserContract.AUTHORITY_URI);
-        return cursor;
+        return new MatrixCursor(Browser.HISTORY_PROJECTION, 0);
     }
-
-    private Cursor doSuggestQuery(String selection, String[] selectionArgs, String limit) {
-        if (TextUtils.isEmpty(selectionArgs[0])) {
-            selection = ZERO_QUERY_SUGGEST_SELECTION;
-            selectionArgs = null;
-        } else {
-            String like = selectionArgs[0] + "%";
-            if (selectionArgs[0].startsWith("http")
-                    || selectionArgs[0].startsWith("file")) {
-                selectionArgs[0] = like;
-            } else {
-                selectionArgs = new String[6];
-                selectionArgs[0] = "http://" + like;
-                selectionArgs[1] = "http://www." + like;
-                selectionArgs[2] = "https://" + like;
-                selectionArgs[3] = "https://www." + like;
-                // To match against titles.
-                selectionArgs[4] = like;
-                selectionArgs[5] = like;
-                selection = SUGGEST_SELECTION;
-            }
-            selection = DatabaseUtils.concatenateWhere(selection,
-                    Bookmarks.IS_DELETED + "=0 AND " + Bookmarks.IS_FOLDER + "=0");
-        }
-
-        Cursor c = mOpenHelper.getReadableDatabase().query(TABLE_BOOKMARKS_JOIN_HISTORY,
-                SUGGEST_PROJECTION, selection, selectionArgs, null, null,
-                null, null);
-
-        return new SuggestionsCursor(c);
-    }
-
-    private String[] createCombinedQuery(
-            Uri uri, String[] projection, SQLiteQueryBuilder qb) {
-        String[] args = null;
-        StringBuilder whereBuilder = new StringBuilder(128);
-        whereBuilder.append(Bookmarks.IS_DELETED);
-        whereBuilder.append(" = 0");
-        // Look for account info
-        Object[] withAccount = getSelectionWithAccounts(uri, null, null);
-        String selection = (String) withAccount[0];
-        String[] selectionArgs = (String[]) withAccount[1];
-        if (selection != null) {
-            whereBuilder.append(" AND " + selection);
-            if (selectionArgs != null) {
-                // We use the selection twice, hence we need to duplicate the args
-                args = new String[selectionArgs.length * 2];
-                System.arraycopy(selectionArgs, 0, args, 0, selectionArgs.length);
-                System.arraycopy(selectionArgs, 0, args, selectionArgs.length,
-                        selectionArgs.length);
-            }
-        }
-        String where = whereBuilder.toString();
-        // Build the bookmark subquery for history union subquery
-        qb.setTables(TABLE_BOOKMARKS);
-        String subQuery = qb.buildQuery(null, where, null, null, null, null);
-        // Build the history union subquery
-        qb.setTables(String.format(FORMAT_COMBINED_JOIN_SUBQUERY_JOIN_IMAGES, subQuery));
-        qb.setProjectionMap(COMBINED_HISTORY_PROJECTION_MAP);
-        String historySubQuery = qb.buildQuery(null,
-                null, null, null, null, null);
-        // Build the bookmark union subquery
-        qb.setTables(TABLE_BOOKMARKS_JOIN_IMAGES);
-        qb.setProjectionMap(COMBINED_BOOKMARK_PROJECTION_MAP);
-        where += String.format(" AND %s NOT IN (SELECT %s FROM %s)",
-                Combined.URL, History.URL, TABLE_HISTORY);
-        String bookmarksSubQuery = qb.buildQuery(null, where,
-                null, null, null, null);
-        // Put it all together
-        String query = qb.buildUnionQuery(
-                new String[] {historySubQuery, bookmarksSubQuery},
-                null, null);
-        qb.setTables("(" + query + ")");
-        qb.setProjectionMap(null);
-        return args;
-    }
-
-    int deleteBookmarks(String selection, String[] selectionArgs,
-            boolean callerIsSyncAdapter) {
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        if (callerIsSyncAdapter) {
-            return db.delete(TABLE_BOOKMARKS, selection, selectionArgs);
-        }
-
-        Object[] appendedBookmarks = appendBookmarksIfFolder(selection, selectionArgs);
-        selection = (String) appendedBookmarks[0];
-        selectionArgs = (String[]) appendedBookmarks[1];
-
-        ContentValues values = new ContentValues();
-        values.put(Bookmarks.DATE_MODIFIED, System.currentTimeMillis());
-        values.put(Bookmarks.IS_DELETED, 1);
-        return updateBookmarksInTransaction(values, selection, selectionArgs,
-                callerIsSyncAdapter);
-    }
-
-    private Object[] appendBookmarksIfFolder(String selection, String[] selectionArgs) {
-        final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-        final String[] bookmarksProjection = new String[] {
-                Bookmarks._ID, // 0
-                Bookmarks.IS_FOLDER // 1
-        };
-        StringBuilder newSelection = new StringBuilder(selection);
-        List<String> newSelectionArgs = new ArrayList<String>();
-
-        Cursor cursor = null;
-        try {
-            cursor = db.query(TABLE_BOOKMARKS, bookmarksProjection,
-                    selection, selectionArgs, null, null, null);
-            if (cursor != null) {
-                while (cursor.moveToNext()) {
-                    String id = Long.toString(cursor.getLong(0));
-                    newSelectionArgs.add(id);
-                    if (cursor.getInt(1) != 0) {
-                        // collect bookmarks in this folder
-                        Object[] bookmarks = appendBookmarksIfFolder(
-                                Bookmarks.PARENT + "=?", new String[] { id });
-                        String[] bookmarkIds = (String[]) bookmarks[1];
-                        if (bookmarkIds.length > 0) {
-                            newSelection.append(" OR " + TABLE_BOOKMARKS + "._id IN (");
-                            for (String bookmarkId : bookmarkIds) {
-                                newSelection.append("?,");
-                                newSelectionArgs.add(bookmarkId);
-                            }
-                            newSelection.deleteCharAt(newSelection.length() - 1);
-                            newSelection.append(")");
-                        }
-                    }
-                }
-            }
-        } finally {
-            if (cursor != null) {
-                cursor.close();
-            }
-        }
-
-        return new Object[] {
-                newSelection.toString(),
-                newSelectionArgs.toArray(new String[newSelectionArgs.size()])
-        };
-    }
-
-    @Override
-    public int deleteInTransaction(Uri uri, String selection, String[] selectionArgs,
-            boolean callerIsSyncAdapter) {
-        final int match = URI_MATCHER.match(uri);
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        int deleted = 0;
-        switch (match) {
-            case BOOKMARKS_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection,
-                        TABLE_BOOKMARKS + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case BOOKMARKS: {
-                // Look for account info
-                Object[] withAccount = getSelectionWithAccounts(uri, selection, selectionArgs);
-                selection = (String) withAccount[0];
-                selectionArgs = (String[]) withAccount[1];
-                deleted = deleteBookmarks(selection, selectionArgs, callerIsSyncAdapter);
-                pruneImages();
-                break;
-            }
-
-            case HISTORY_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case HISTORY: {
-                filterSearchClient(selectionArgs);
-                deleted = db.delete(TABLE_HISTORY, selection, selectionArgs);
-                pruneImages();
-                break;
-            }
-
-            case SEARCHES_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection, TABLE_SEARCHES + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case SEARCHES: {
-                deleted = db.delete(TABLE_SEARCHES, selection, selectionArgs);
-                break;
-            }
-
-            case SYNCSTATE: {
-                deleted = mSyncHelper.delete(db, selection, selectionArgs);
-                break;
-            }
-            case SYNCSTATE_ID: {
-                String selectionWithId =
-                        (SyncStateContract.Columns._ID + "=" + ContentUris.parseId(uri) + " ")
-                        + (selection == null ? "" : " AND (" + selection + ")");
-                deleted = mSyncHelper.delete(db, selectionWithId, selectionArgs);
-                break;
-            }
-            case LEGACY_ID: {
-                selection = DatabaseUtils.concatenateWhere(
-                        selection, Combined._ID + " = CAST(? AS INTEGER)");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case LEGACY: {
-                String[] projection = new String[] { Combined._ID,
-                        Combined.IS_BOOKMARK, Combined.URL };
-                SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-                String[] args = createCombinedQuery(uri, projection, qb);
-                if (selectionArgs == null) {
-                    selectionArgs = args;
-                } else {
-                    selectionArgs = DatabaseUtils.appendSelectionArgs(
-                            args, selectionArgs);
-                }
-                Cursor c = qb.query(db, projection, selection, selectionArgs,
-                        null, null, null);
-                while (c.moveToNext()) {
-                    long id = c.getLong(0);
-                    boolean isBookmark = c.getInt(1) != 0;
-                    String url = c.getString(2);
-                    if (isBookmark) {
-                        deleted += deleteBookmarks(Bookmarks._ID + "=?",
-                                new String[] { Long.toString(id) },
-                                callerIsSyncAdapter);
-                        db.delete(TABLE_HISTORY, History.URL + "=?",
-                                new String[] { url });
-                    } else {
-                        deleted += db.delete(TABLE_HISTORY,
-                                Bookmarks._ID + "=?",
-                                new String[] { Long.toString(id) });
-                    }
-                }
-                c.close();
-                break;
-            }
-            case THUMBNAILS_ID: {
-                selection = DatabaseUtils.concatenateWhere(
-                        selection, Thumbnails._ID + " = ?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case THUMBNAILS: {
-                deleted = db.delete(TABLE_THUMBNAILS, selection, selectionArgs);
-                break;
-            }
-            default: {
-                throw new UnsupportedOperationException("Unknown delete URI " + uri);
-            }
-        }
-        if (deleted > 0) {
-            postNotifyUri(uri);
-            if (shouldNotifyLegacy(uri)) {
-                postNotifyUri(LEGACY_AUTHORITY_URI);
-            }
-        }
-        return deleted;
-    }
-
-    long queryDefaultFolderId(String accountName, String accountType) {
-        if (!isNullAccount(accountName) && !isNullAccount(accountType)) {
-            final SQLiteDatabase db = mOpenHelper.getReadableDatabase();
-            Cursor c = db.query(TABLE_BOOKMARKS, new String[] { Bookmarks._ID },
-                    ChromeSyncColumns.SERVER_UNIQUE + " = ?" +
-                    " AND account_type = ? AND account_name = ?",
-                    new String[] { ChromeSyncColumns.FOLDER_NAME_BOOKMARKS_BAR,
-                    accountType, accountName }, null, null, null);
-            try {
-                if (c.moveToFirst()) {
-                    return c.getLong(0);
-                }
-            } finally {
-                c.close();
-            }
-        }
-        return FIXED_ID_ROOT;
-    }
-
-    @Override
-    public Uri insertInTransaction(Uri uri, ContentValues values, boolean callerIsSyncAdapter) {
-        int match = URI_MATCHER.match(uri);
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        long id = -1;
-        if (match == LEGACY) {
-            // Intercept and route to the correct table
-            Integer bookmark = values.getAsInteger(BookmarkColumns.BOOKMARK);
-            values.remove(BookmarkColumns.BOOKMARK);
-            if (bookmark == null || bookmark == 0) {
-                match = HISTORY;
-            } else {
-                match = BOOKMARKS;
-                values.remove(BookmarkColumns.DATE);
-                values.remove(BookmarkColumns.VISITS);
-                values.remove(BookmarkColumns.USER_ENTERED);
-                values.put(Bookmarks.IS_FOLDER, 0);
-            }
-        }
-        switch (match) {
-            case BOOKMARKS: {
-                // Mark rows dirty if they're not coming from a sync adapter
-                if (!callerIsSyncAdapter) {
-                    long now = System.currentTimeMillis();
-                    values.put(Bookmarks.DATE_CREATED, now);
-                    values.put(Bookmarks.DATE_MODIFIED, now);
-                    values.put(Bookmarks.DIRTY, 1);
-
-                    boolean hasAccounts = values.containsKey(Bookmarks.ACCOUNT_TYPE)
-                            || values.containsKey(Bookmarks.ACCOUNT_NAME);
-                    String accountType = values
-                            .getAsString(Bookmarks.ACCOUNT_TYPE);
-                    String accountName = values
-                            .getAsString(Bookmarks.ACCOUNT_NAME);
-                    boolean hasParent = values.containsKey(Bookmarks.PARENT);
-                    if (hasParent && hasAccounts) {
-                        // Let's make sure it's valid
-                        long parentId = values.getAsLong(Bookmarks.PARENT);
-                        hasParent = isValidParent(
-                                accountType, accountName, parentId);
-                    } else if (hasParent && !hasAccounts) {
-                        long parentId = values.getAsLong(Bookmarks.PARENT);
-                        hasParent = setParentValues(parentId, values);
-                    }
-
-                    // If no parent is set default to the "Bookmarks Bar" folder
-                    if (!hasParent) {
-                        values.put(Bookmarks.PARENT,
-                                queryDefaultFolderId(accountName, accountType));
-                    }
-                }
-
-                // If no position is requested put the bookmark at the beginning of the list
-                if (!values.containsKey(Bookmarks.POSITION)) {
-                    values.put(Bookmarks.POSITION, Long.toString(Long.MIN_VALUE));
-                }
-
-                // Extract out the image values so they can be inserted into the images table
-                String url = values.getAsString(Bookmarks.URL);
-                ContentValues imageValues = extractImageValues(values, url);
-                Boolean isFolder = values.getAsBoolean(Bookmarks.IS_FOLDER);
-                if ((isFolder == null || !isFolder)
-                        && imageValues != null && !TextUtils.isEmpty(url)) {
-                    int count = db.update(TABLE_IMAGES, imageValues, Images.URL + "=?",
-                            new String[] { url });
-                    if (count == 0) {
-                        db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, imageValues);
-                    }
-                }
-
-                id = db.insertOrThrow(TABLE_BOOKMARKS, Bookmarks.DIRTY, values);
-                break;
-            }
-
-            case HISTORY: {
-                // If no created time is specified set it to now
-                if (!values.containsKey(History.DATE_CREATED)) {
-                    values.put(History.DATE_CREATED, System.currentTimeMillis());
-                }
-                String url = values.getAsString(History.URL);
-                url = filterSearchClient(url);
-                values.put(History.URL, url);
-
-                // Extract out the image values so they can be inserted into the images table
-                ContentValues imageValues = extractImageValues(values,
-                        values.getAsString(History.URL));
-                if (imageValues != null) {
-                    db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, imageValues);
-                }
-
-                id = db.insertOrThrow(TABLE_HISTORY, History.VISITS, values);
-                break;
-            }
-
-            case SEARCHES: {
-                id = insertSearchesInTransaction(db, values);
-                break;
-            }
-
-            case SYNCSTATE: {
-                id = mSyncHelper.insert(db, values);
-                break;
-            }
-
-            case SETTINGS: {
-                id = 0;
-                insertSettingsInTransaction(db, values);
-                break;
-            }
-
-            case THUMBNAILS: {
-                id = db.replaceOrThrow(TABLE_THUMBNAILS, null, values);
-                break;
-            }
-
-            default: {
-                throw new UnsupportedOperationException("Unknown insert URI " + uri);
-            }
-        }
-
-        if (id >= 0) {
-            postNotifyUri(uri);
-            if (shouldNotifyLegacy(uri)) {
-                postNotifyUri(LEGACY_AUTHORITY_URI);
-            }
-            return ContentUris.withAppendedId(uri, id);
-        } else {
-            return null;
-        }
-    }
-
-    private String[] getAccountNameAndType(long id) {
-        if (id <= 0) {
-            return null;
-        }
-        Uri uri = ContentUris.withAppendedId(Bookmarks.CONTENT_URI, id);
-        Cursor c = query(uri,
-                new String[] { Bookmarks.ACCOUNT_NAME, Bookmarks.ACCOUNT_TYPE },
-                null, null, null);
-        try {
-            if (c.moveToFirst()) {
-                String parentName = c.getString(0);
-                String parentType = c.getString(1);
-                return new String[] { parentName, parentType };
-            }
-            return null;
-        } finally {
-            c.close();
-        }
-    }
-
-    private boolean setParentValues(long parentId, ContentValues values) {
-        String[] parent = getAccountNameAndType(parentId);
-        if (parent == null) {
-            return false;
-        }
-        values.put(Bookmarks.ACCOUNT_NAME, parent[0]);
-        values.put(Bookmarks.ACCOUNT_TYPE, parent[1]);
-        return true;
-    }
-
-    private boolean isValidParent(String accountType, String accountName,
-            long parentId) {
-        String[] parent = getAccountNameAndType(parentId);
-        if (parent != null
-                && TextUtils.equals(accountName, parent[0])
-                && TextUtils.equals(accountType, parent[1])) {
-            return true;
-        }
-        return false;
-    }
-
-    private void filterSearchClient(String[] selectionArgs) {
-        if (selectionArgs != null) {
-            for (int i = 0; i < selectionArgs.length; i++) {
-                selectionArgs[i] = filterSearchClient(selectionArgs[i]);
-            }
-        }
-    }
-
-    // Filters out the client= param for search urls
-    private String filterSearchClient(String url) {
-        // remove "client" before updating it to the history so that it wont
-        // show up in the auto-complete list.
-        int index = url.indexOf("client=");
-        if (index > 0 && url.contains(".google.")) {
-            int end = url.indexOf('&', index);
-            if (end > 0) {
-                url = url.substring(0, index)
-                        .concat(url.substring(end + 1));
-            } else {
-                // the url.charAt(index-1) should be either '?' or '&'
-                url = url.substring(0, index-1);
-            }
-        }
-        return url;
-    }
-
-    /**
-     * Searches are unique, so perform an UPSERT manually since SQLite doesn't support them.
-     */
-    private long insertSearchesInTransaction(SQLiteDatabase db, ContentValues values) {
-        String search = values.getAsString(Searches.SEARCH);
-        if (TextUtils.isEmpty(search)) {
-            throw new IllegalArgumentException("Must include the SEARCH field");
-        }
-        Cursor cursor = null;
-        try {
-            cursor = db.query(TABLE_SEARCHES, new String[] { Searches._ID },
-                    Searches.SEARCH + "=?", new String[] { search }, null, null, null);
-            if (cursor.moveToNext()) {
-                long id = cursor.getLong(0);
-                db.update(TABLE_SEARCHES, values, Searches._ID + "=?",
-                        new String[] { Long.toString(id) });
-                return id;
-            } else {
-                return db.insertOrThrow(TABLE_SEARCHES, Searches.SEARCH, values);
-            }
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-    }
-
-    /**
-     * Settings are unique, so perform an UPSERT manually since SQLite doesn't support them.
-     */
-    private long insertSettingsInTransaction(SQLiteDatabase db, ContentValues values) {
-        String key = values.getAsString(Settings.KEY);
-        if (TextUtils.isEmpty(key)) {
-            throw new IllegalArgumentException("Must include the KEY field");
-        }
-        String[] keyArray = new String[] { key };
-        Cursor cursor = null;
-        try {
-            cursor = db.query(TABLE_SETTINGS, new String[] { Settings.KEY },
-                    Settings.KEY + "=?", keyArray, null, null, null);
-            if (cursor.moveToNext()) {
-                long id = cursor.getLong(0);
-                db.update(TABLE_SETTINGS, values, Settings.KEY + "=?", keyArray);
-                return id;
-            } else {
-                return db.insertOrThrow(TABLE_SETTINGS, Settings.VALUE, values);
-            }
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-    }
-
-    @Override
-    public int updateInTransaction(Uri uri, ContentValues values, String selection,
-            String[] selectionArgs, boolean callerIsSyncAdapter) {
-        int match = URI_MATCHER.match(uri);
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        if (match == LEGACY || match == LEGACY_ID) {
-            // Intercept and route to the correct table
-            Integer bookmark = values.getAsInteger(BookmarkColumns.BOOKMARK);
-            values.remove(BookmarkColumns.BOOKMARK);
-            if (bookmark == null || bookmark == 0) {
-                if (match == LEGACY) {
-                    match = HISTORY;
-                } else {
-                    match = HISTORY_ID;
-                }
-            } else {
-                if (match == LEGACY) {
-                    match = BOOKMARKS;
-                } else {
-                    match = BOOKMARKS_ID;
-                }
-                values.remove(BookmarkColumns.DATE);
-                values.remove(BookmarkColumns.VISITS);
-                values.remove(BookmarkColumns.USER_ENTERED);
-            }
-        }
-        int modified = 0;
-        switch (match) {
-            case BOOKMARKS_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection,
-                        TABLE_BOOKMARKS + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case BOOKMARKS: {
-                Object[] withAccount = getSelectionWithAccounts(uri, selection, selectionArgs);
-                selection = (String) withAccount[0];
-                selectionArgs = (String[]) withAccount[1];
-                modified = updateBookmarksInTransaction(values, selection, selectionArgs,
-                        callerIsSyncAdapter);
-                break;
-            }
-
-            case HISTORY_ID: {
-                selection = DatabaseUtils.concatenateWhere(selection, TABLE_HISTORY + "._id=?");
-                selectionArgs = DatabaseUtils.appendSelectionArgs(selectionArgs,
-                        new String[] { Long.toString(ContentUris.parseId(uri)) });
-                // fall through
-            }
-            case HISTORY: {
-                modified = updateHistoryInTransaction(values, selection, selectionArgs);
-                break;
-            }
-
-            case SYNCSTATE: {
-                modified = mSyncHelper.update(mDb, values,
-                        appendAccountToSelection(uri, selection), selectionArgs);
-                break;
-            }
-
-            case SYNCSTATE_ID: {
-                selection = appendAccountToSelection(uri, selection);
-                String selectionWithId =
-                        (SyncStateContract.Columns._ID + "=" + ContentUris.parseId(uri) + " ")
-                        + (selection == null ? "" : " AND (" + selection + ")");
-                modified = mSyncHelper.update(mDb, values,
-                        selectionWithId, selectionArgs);
-                break;
-            }
-
-            case IMAGES: {
-                String url = values.getAsString(Images.URL);
-                if (TextUtils.isEmpty(url)) {
-                    throw new IllegalArgumentException("Images.URL is required");
-                }
-                if (!shouldUpdateImages(db, url, values)) {
-                    return 0;
-                }
-                int count = db.update(TABLE_IMAGES, values, Images.URL + "=?",
-                        new String[] { url });
-                if (count == 0) {
-                    db.insertOrThrow(TABLE_IMAGES, Images.FAVICON, values);
-                    count = 1;
-                }
-                // Only favicon is exposed in the public API. If we updated
-                // the thumbnail or touch icon don't bother notifying the
-                // legacy authority since it can't read it anyway.
-                boolean updatedLegacy = false;
-                if (getUrlCount(db, TABLE_BOOKMARKS, url) > 0) {
-                    postNotifyUri(Bookmarks.CONTENT_URI);
-                    updatedLegacy = values.containsKey(Images.FAVICON);
-                }
-                if (getUrlCount(db, TABLE_HISTORY, url) > 0) {
-                    postNotifyUri(History.CONTENT_URI);
-                    updatedLegacy = values.containsKey(Images.FAVICON);
-                }
-                if (pruneImages() > 0 || updatedLegacy) {
-                    postNotifyUri(LEGACY_AUTHORITY_URI);
-                }
-                return count;
-            }
-
-            case SEARCHES: {
-                modified = db.update(TABLE_SEARCHES, values, selection, selectionArgs);
-                break;
-            }
-
-            case ACCOUNTS: {
-                Account[] accounts = AccountManager.get(getContext()).getAccounts();
-                mSyncHelper.onAccountsChanged(mDb, accounts);
-                break;
-            }
-
-            case THUMBNAILS: {
-                modified = db.update(TABLE_THUMBNAILS, values,
-                        selection, selectionArgs);
-                break;
-            }
-
-            default: {
-                throw new UnsupportedOperationException("Unknown update URI " + uri);
-            }
-        }
-        pruneImages();
-        if (modified > 0) {
-            postNotifyUri(uri);
-            if (shouldNotifyLegacy(uri)) {
-                postNotifyUri(LEGACY_AUTHORITY_URI);
-            }
-        }
-        return modified;
-    }
-
-    // We want to avoid sending out more URI notifications than we have to
-    // Thus, we check to see if the images we are about to store are already there
-    // This is used because things like a site's favion or touch icon is rarely
-    // changed, but the browser tries to update it every time the page loads.
-    // Without this, we will always send out 3 URI notifications per page load.
-    // With this, that drops to 0 or 1, depending on if the thumbnail changed.
-    private boolean shouldUpdateImages(
-            SQLiteDatabase db, String url, ContentValues values) {
-        final String[] projection = new String[] {
-                Images.FAVICON,
-                Images.THUMBNAIL,
-                Images.TOUCH_ICON,
-        };
-        Cursor cursor = db.query(TABLE_IMAGES, projection, Images.URL + "=?",
-                new String[] { url }, null, null, null);
-        byte[] nfavicon = values.getAsByteArray(Images.FAVICON);
-        byte[] nthumb = values.getAsByteArray(Images.THUMBNAIL);
-        byte[] ntouch = values.getAsByteArray(Images.TOUCH_ICON);
-        byte[] cfavicon = null;
-        byte[] cthumb = null;
-        byte[] ctouch = null;
-        try {
-            if (cursor.getCount() <= 0) {
-                return nfavicon != null || nthumb != null || ntouch != null;
-            }
-            while (cursor.moveToNext()) {
-                if (nfavicon != null) {
-                    cfavicon = cursor.getBlob(0);
-                    if (!Arrays.equals(nfavicon, cfavicon)) {
-                        return true;
-                    }
-                }
-                if (nthumb != null) {
-                    cthumb = cursor.getBlob(1);
-                    if (!Arrays.equals(nthumb, cthumb)) {
-                        return true;
-                    }
-                }
-                if (ntouch != null) {
-                    ctouch = cursor.getBlob(2);
-                    if (!Arrays.equals(ntouch, ctouch)) {
-                        return true;
-                    }
-                }
-            }
-        } finally {
-            cursor.close();
-        }
-        return false;
-    }
-
-    int getUrlCount(SQLiteDatabase db, String table, String url) {
-        Cursor c = db.query(table, new String[] { "COUNT(*)" },
-                "url = ?", new String[] { url }, null, null, null);
-        try {
-            int count = 0;
-            if (c.moveToFirst()) {
-                count = c.getInt(0);
-            }
-            return count;
-        } finally {
-            c.close();
-        }
-    }
-
-    /**
-     * Does a query to find the matching bookmarks and updates each one with the provided values.
-     */
-    int updateBookmarksInTransaction(ContentValues values, String selection,
-            String[] selectionArgs, boolean callerIsSyncAdapter) {
-        int count = 0;
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        final String[] bookmarksProjection = new String[] {
-                Bookmarks._ID, // 0
-                Bookmarks.VERSION, // 1
-                Bookmarks.URL, // 2
-                Bookmarks.TITLE, // 3
-                Bookmarks.IS_FOLDER, // 4
-                Bookmarks.ACCOUNT_NAME, // 5
-                Bookmarks.ACCOUNT_TYPE, // 6
-        };
-        Cursor cursor = db.query(TABLE_BOOKMARKS, bookmarksProjection,
-                selection, selectionArgs, null, null, null);
-        boolean updatingParent = values.containsKey(Bookmarks.PARENT);
-        String parentAccountName = null;
-        String parentAccountType = null;
-        if (updatingParent) {
-            long parent = values.getAsLong(Bookmarks.PARENT);
-            Cursor c = db.query(TABLE_BOOKMARKS, new String[] {
-                    Bookmarks.ACCOUNT_NAME, Bookmarks.ACCOUNT_TYPE},
-                    "_id = ?", new String[] { Long.toString(parent) },
-                    null, null, null);
-            if (c.moveToFirst()) {
-                parentAccountName = c.getString(0);
-                parentAccountType = c.getString(1);
-            }
-            c.close();
-        } else if (values.containsKey(Bookmarks.ACCOUNT_NAME)
-                || values.containsKey(Bookmarks.ACCOUNT_TYPE)) {
-            // TODO: Implement if needed (no one needs this yet)
-        }
-        try {
-            String[] args = new String[1];
-            // Mark the bookmark dirty if the caller isn't a sync adapter
-            if (!callerIsSyncAdapter) {
-                values.put(Bookmarks.DATE_MODIFIED, System.currentTimeMillis());
-                values.put(Bookmarks.DIRTY, 1);
-            }
-
-            boolean updatingUrl = values.containsKey(Bookmarks.URL);
-            String url = null;
-            if (updatingUrl) {
-                url = values.getAsString(Bookmarks.URL);
-            }
-            ContentValues imageValues = extractImageValues(values, url);
-
-            while (cursor.moveToNext()) {
-                long id = cursor.getLong(0);
-                args[0] = Long.toString(id);
-                String accountName = cursor.getString(5);
-                String accountType = cursor.getString(6);
-                // If we are updating the parent and either the account name or
-                // type do not match that of the new parent
-                if (updatingParent
-                        && (!TextUtils.equals(accountName, parentAccountName)
-                        || !TextUtils.equals(accountType, parentAccountType))) {
-                    // Parent is a different account
-                    // First, insert a new bookmark/folder with the new account
-                    // Then, if this is a folder, reparent all it's children
-                    // Finally, delete the old bookmark/folder
-                    ContentValues newValues = valuesFromCursor(cursor);
-                    newValues.putAll(values);
-                    newValues.remove(Bookmarks._ID);
-                    newValues.remove(Bookmarks.VERSION);
-                    newValues.put(Bookmarks.ACCOUNT_NAME, parentAccountName);
-                    newValues.put(Bookmarks.ACCOUNT_TYPE, parentAccountType);
-                    Uri insertUri = insertInTransaction(Bookmarks.CONTENT_URI,
-                            newValues, callerIsSyncAdapter);
-                    long newId = ContentUris.parseId(insertUri);
-                    if (cursor.getInt(4) != 0) {
-                        // This is a folder, reparent
-                        ContentValues updateChildren = new ContentValues(1);
-                        updateChildren.put(Bookmarks.PARENT, newId);
-                        count += updateBookmarksInTransaction(updateChildren,
-                                Bookmarks.PARENT + "=?", new String[] {
-                                Long.toString(id)}, callerIsSyncAdapter);
-                    }
-                    // Now, delete the old one
-                    Uri uri = ContentUris.withAppendedId(Bookmarks.CONTENT_URI, id);
-                    deleteInTransaction(uri, null, null, callerIsSyncAdapter);
-                    count += 1;
-                } else {
-                    if (!callerIsSyncAdapter) {
-                        // increase the local version for non-sync changes
-                        values.put(Bookmarks.VERSION, cursor.getLong(1) + 1);
-                    }
-                    count += db.update(TABLE_BOOKMARKS, values, "_id=?", args);
-                }
-
-                // Update the images over in their table
-                if (imageValues != null) {
-                    if (!updatingUrl) {
-                        url = cursor.getString(2);
-                        imageValues.put(Images.URL, url);
-                    }
-
-                    if (!TextUtils.isEmpty(url)) {
-                        args[0] = url;
-                        if (db.update(TABLE_IMAGES, imageValues, Images.URL + "=?", args) == 0) {
-                            db.insert(TABLE_IMAGES, Images.FAVICON, imageValues);
-                        }
-                    }
-                }
-            }
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-        return count;
-    }
-
-    ContentValues valuesFromCursor(Cursor c) {
-        int count = c.getColumnCount();
-        ContentValues values = new ContentValues(count);
-        String[] colNames = c.getColumnNames();
-        for (int i = 0; i < count; i++) {
-            switch (c.getType(i)) {
-            case Cursor.FIELD_TYPE_BLOB:
-                values.put(colNames[i], c.getBlob(i));
-                break;
-            case Cursor.FIELD_TYPE_FLOAT:
-                values.put(colNames[i], c.getFloat(i));
-                break;
-            case Cursor.FIELD_TYPE_INTEGER:
-                values.put(colNames[i], c.getLong(i));
-                break;
-            case Cursor.FIELD_TYPE_STRING:
-                values.put(colNames[i], c.getString(i));
-                break;
-            }
-        }
-        return values;
-    }
-
-    /**
-     * Does a query to find the matching bookmarks and updates each one with the provided values.
-     */
-    int updateHistoryInTransaction(ContentValues values, String selection, String[] selectionArgs) {
-        int count = 0;
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        filterSearchClient(selectionArgs);
-        Cursor cursor = query(History.CONTENT_URI,
-                new String[] { History._ID, History.URL },
-                selection, selectionArgs, null);
-        try {
-            String[] args = new String[1];
-
-            boolean updatingUrl = values.containsKey(History.URL);
-            String url = null;
-            if (updatingUrl) {
-                url = filterSearchClient(values.getAsString(History.URL));
-                values.put(History.URL, url);
-            }
-            ContentValues imageValues = extractImageValues(values, url);
-
-            while (cursor.moveToNext()) {
-                args[0] = cursor.getString(0);
-                count += db.update(TABLE_HISTORY, values, "_id=?", args);
-
-                // Update the images over in their table
-                if (imageValues != null) {
-                    if (!updatingUrl) {
-                        url = cursor.getString(1);
-                        imageValues.put(Images.URL, url);
-                    }
-                    args[0] = url;
-                    if (db.update(TABLE_IMAGES, imageValues, Images.URL + "=?", args) == 0) {
-                        db.insert(TABLE_IMAGES, Images.FAVICON, imageValues);
-                    }
-                }
-            }
-        } finally {
-            if (cursor != null) cursor.close();
-        }
-        return count;
-    }
-
-    String appendAccountToSelection(Uri uri, String selection) {
-        final String accountName = uri.getQueryParameter(RawContacts.ACCOUNT_NAME);
-        final String accountType = uri.getQueryParameter(RawContacts.ACCOUNT_TYPE);
-
-        final boolean partialUri = TextUtils.isEmpty(accountName) ^ TextUtils.isEmpty(accountType);
-        if (partialUri) {
-            // Throw when either account is incomplete
-            throw new IllegalArgumentException(
-                    "Must specify both or neither of ACCOUNT_NAME and ACCOUNT_TYPE for " + uri);
-        }
-
-        // Accounts are valid by only checking one parameter, since we've
-        // already ruled out partial accounts.
-        final boolean validAccount = !TextUtils.isEmpty(accountName);
-        if (validAccount) {
-            StringBuilder selectionSb = new StringBuilder(RawContacts.ACCOUNT_NAME + "="
-                    + DatabaseUtils.sqlEscapeString(accountName) + " AND "
-                    + RawContacts.ACCOUNT_TYPE + "="
-                    + DatabaseUtils.sqlEscapeString(accountType));
-            if (!TextUtils.isEmpty(selection)) {
-                selectionSb.append(" AND (");
-                selectionSb.append(selection);
-                selectionSb.append(')');
-            }
-            return selectionSb.toString();
-        } else {
-            return selection;
-        }
-    }
-
-    ContentValues extractImageValues(ContentValues values, String url) {
-        ContentValues imageValues = null;
-        // favicon
-        if (values.containsKey(Bookmarks.FAVICON)) {
-            imageValues = new ContentValues();
-            imageValues.put(Images.FAVICON, values.getAsByteArray(Bookmarks.FAVICON));
-            values.remove(Bookmarks.FAVICON);
-        }
-
-        // thumbnail
-        if (values.containsKey(Bookmarks.THUMBNAIL)) {
-            if (imageValues == null) {
-                imageValues = new ContentValues();
-            }
-            imageValues.put(Images.THUMBNAIL, values.getAsByteArray(Bookmarks.THUMBNAIL));
-            values.remove(Bookmarks.THUMBNAIL);
-        }
-
-        // touch icon
-        if (values.containsKey(Bookmarks.TOUCH_ICON)) {
-            if (imageValues == null) {
-                imageValues = new ContentValues();
-            }
-            imageValues.put(Images.TOUCH_ICON, values.getAsByteArray(Bookmarks.TOUCH_ICON));
-            values.remove(Bookmarks.TOUCH_ICON);
-        }
-
-        if (imageValues != null) {
-            imageValues.put(Images.URL,  url);
-        }
-        return imageValues;
-    }
-
-    int pruneImages() {
-        final SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-        return db.delete(TABLE_IMAGES, IMAGE_PRUNE, null);
-    }
-
-    boolean shouldNotifyLegacy(Uri uri) {
-        if (uri.getPathSegments().contains("history")
-                || uri.getPathSegments().contains("bookmarks")
-                || uri.getPathSegments().contains("searches")) {
-            return true;
-        }
-        return false;
-    }
-
-    static class SuggestionsCursor extends AbstractCursor {
-        private static final int ID_INDEX = 0;
-        private static final int URL_INDEX = 1;
-        private static final int TITLE_INDEX = 2;
-        private static final int ICON_INDEX = 3;
-        private static final int LAST_ACCESS_TIME_INDEX = 4;
-        // shared suggestion array index, make sure to match COLUMNS
-        private static final int SUGGEST_COLUMN_INTENT_ACTION_ID = 1;
-        private static final int SUGGEST_COLUMN_INTENT_DATA_ID = 2;
-        private static final int SUGGEST_COLUMN_TEXT_1_ID = 3;
-        private static final int SUGGEST_COLUMN_TEXT_2_TEXT_ID = 4;
-        private static final int SUGGEST_COLUMN_TEXT_2_URL_ID = 5;
-        private static final int SUGGEST_COLUMN_ICON_1_ID = 6;
-        private static final int SUGGEST_COLUMN_LAST_ACCESS_HINT_ID = 7;
-
-        // shared suggestion columns
-        private static final String[] COLUMNS = new String[] {
-                BaseColumns._ID,
-                SearchManager.SUGGEST_COLUMN_INTENT_ACTION,
-                SearchManager.SUGGEST_COLUMN_INTENT_DATA,
-                SearchManager.SUGGEST_COLUMN_TEXT_1,
-                SearchManager.SUGGEST_COLUMN_TEXT_2,
-                SearchManager.SUGGEST_COLUMN_TEXT_2_URL,
-                SearchManager.SUGGEST_COLUMN_ICON_1,
-                SearchManager.SUGGEST_COLUMN_LAST_ACCESS_HINT};
-
-        private final Cursor mSource;
-
-        public SuggestionsCursor(Cursor cursor) {
-            mSource = cursor;
-        }
-
-        @Override
-        public String[] getColumnNames() {
-            return COLUMNS;
-        }
-
-        // Regular expression to strip http:// and optionally
-        // the trailing slash
-        private static final Pattern STRIP_URL_PATTERN =
-                Pattern.compile("^http://(.*?)/?$");
-
-        /**
-         * Strips the provided url of preceding "http://" and any trailing "/". Does not
-         * strip "https://". If the provided string cannot be stripped, the original string
-         * is returned.
-         *
-         * TODO: Put this in TextUtils to be used by other packages doing something similar.
-         *
-         * @param url a url to strip, like "http://www.google.com/"
-         * @return a stripped url like "www.google.com", or the original string if it could
-         *         not be stripped
-         */
-        private static String stripUrl(String url) {
-            if (url == null) return null;
-            Matcher m = STRIP_URL_PATTERN.matcher(url);
-            if (m.matches()) {
-                return m.group(1);
-            } else {
-                return url;
-            }
-        }
-
-        @Override
-        public String getString(int columnIndex) {
-            switch (columnIndex) {
-            case ID_INDEX:
-                return mSource.getString(columnIndex);
-            case SUGGEST_COLUMN_INTENT_ACTION_ID:
-                return Intent.ACTION_VIEW;
-            case SUGGEST_COLUMN_INTENT_DATA_ID:
-                return mSource.getString(URL_INDEX);
-            case SUGGEST_COLUMN_TEXT_2_TEXT_ID:
-            case SUGGEST_COLUMN_TEXT_2_URL_ID:
-                return stripUrl(mSource.getString(URL_INDEX));
-            case SUGGEST_COLUMN_TEXT_1_ID:
-                return mSource.getString(TITLE_INDEX);
-            case SUGGEST_COLUMN_ICON_1_ID:
-                return mSource.getString(ICON_INDEX);
-            case SUGGEST_COLUMN_LAST_ACCESS_HINT_ID:
-                return mSource.getString(LAST_ACCESS_TIME_INDEX);
-            }
-            return null;
-        }
-
-        @Override
-        public int getCount() {
-            return mSource.getCount();
-        }
-
-        @Override
-        public double getDouble(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public float getFloat(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public int getInt(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public long getLong(int column) {
-            switch (column) {
-            case ID_INDEX:
-                return mSource.getLong(ID_INDEX);
-            case SUGGEST_COLUMN_LAST_ACCESS_HINT_ID:
-                return mSource.getLong(LAST_ACCESS_TIME_INDEX);
-            }
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public short getShort(int column) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        public boolean isNull(int column) {
-            return mSource.isNull(column);
-        }
-
-        @Override
-        public boolean onMove(int oldPosition, int newPosition) {
-            return mSource.moveToPosition(newPosition);
-        }
-    }
-
-    // ---------------------------------------------------
-    //  SQL below, be warned
-    // ---------------------------------------------------
-
-    private static final String SQL_CREATE_VIEW_OMNIBOX_SUGGESTIONS =
-            "CREATE VIEW IF NOT EXISTS v_omnibox_suggestions "
-            + " AS "
-            + "  SELECT _id, url, title, 1 AS bookmark, 0 AS visits, 0 AS date"
-            + "  FROM bookmarks "
-            + "  WHERE deleted = 0 AND folder = 0 "
-            + "  UNION ALL "
-            + "  SELECT _id, url, title, 0 AS bookmark, visits, date "
-            + "  FROM history "
-            + "  WHERE url NOT IN (SELECT url FROM bookmarks"
-            + "    WHERE deleted = 0 AND folder = 0) "
-            + "  ORDER BY bookmark DESC, visits DESC, date DESC ";
-
-    private static final String SQL_WHERE_ACCOUNT_HAS_BOOKMARKS =
-            "0 < ( "
-            + "SELECT count(*) "
-            + "FROM bookmarks "
-            + "WHERE deleted = 0 AND folder = 0 "
-            + "  AND ( "
-            + "    v_accounts.account_name = bookmarks.account_name "
-            + "    OR (v_accounts.account_name IS NULL AND bookmarks.account_name IS NULL) "
-            + "  ) "
-            + "  AND ( "
-            + "    v_accounts.account_type = bookmarks.account_type "
-            + "    OR (v_accounts.account_type IS NULL AND bookmarks.account_type IS NULL) "
-            + "  ) "
-            + ")";
 }
diff --git a/src/com/android/bookmarkstore/SQLiteContentProvider.java b/src/com/android/bookmarkstore/SQLiteContentProvider.java
deleted file mode 100644
index c202a57..0000000
--- a/src/com/android/bookmarkstore/SQLiteContentProvider.java
+++ /dev/null
@@ -1,250 +0,0 @@
-/*
- * Copyright (C) 2009 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.bookmarkprovider;
-
-import android.content.ContentProvider;
-import android.content.ContentProviderOperation;
-import android.content.ContentProviderResult;
-import android.content.ContentResolver;
-import android.content.ContentValues;
-import android.content.Context;
-import android.content.OperationApplicationException;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteOpenHelper;
-import android.net.Uri;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * General purpose {@link ContentProvider} base class that uses SQLiteDatabase for storage.
- */
-public abstract class SQLiteContentProvider extends ContentProvider {
-
-    private static final String TAG = "SQLiteContentProvider";
-
-    private SQLiteOpenHelper mOpenHelper;
-    private Set<Uri> mChangedUris;
-    protected SQLiteDatabase mDb;
-
-    private final ThreadLocal<Boolean> mApplyingBatch = new ThreadLocal<Boolean>();
-    private static final int SLEEP_AFTER_YIELD_DELAY = 4000;
-
-    /**
-     * Maximum number of operations allowed in a batch between yield points.
-     */
-    private static final int MAX_OPERATIONS_PER_YIELD_POINT = 500;
-
-    @Override
-    public boolean onCreate() {
-        Context context = getContext();
-        mOpenHelper = getDatabaseHelper(context);
-        mChangedUris = new HashSet<Uri>();
-        return true;
-    }
-
-    /**
-     * Returns a {@link SQLiteOpenHelper} that can open the database.
-     */
-    public abstract SQLiteOpenHelper getDatabaseHelper(Context context);
-
-    /**
-     * The equivalent of the {@link #insert} method, but invoked within a transaction.
-     */
-    public abstract Uri insertInTransaction(Uri uri, ContentValues values,
-            boolean callerIsSyncAdapter);
-
-    /**
-     * The equivalent of the {@link #update} method, but invoked within a transaction.
-     */
-    public abstract int updateInTransaction(Uri uri, ContentValues values, String selection,
-            String[] selectionArgs, boolean callerIsSyncAdapter);
-
-    /**
-     * The equivalent of the {@link #delete} method, but invoked within a transaction.
-     */
-    public abstract int deleteInTransaction(Uri uri, String selection, String[] selectionArgs,
-            boolean callerIsSyncAdapter);
-
-    /**
-     * Call this to add a URI to the list of URIs to be notified when the transaction
-     * is committed.
-     */
-    protected void postNotifyUri(Uri uri) {
-        synchronized (mChangedUris) {
-            mChangedUris.add(uri);
-        }
-    }
-
-    public boolean isCallerSyncAdapter(Uri uri) {
-        return false;
-    }
-
-    public SQLiteOpenHelper getDatabaseHelper() {
-        return mOpenHelper;
-    }
-
-    private boolean applyingBatch() {
-        return mApplyingBatch.get() != null && mApplyingBatch.get();
-    }
-
-    @Override
-    public Uri insert(Uri uri, ContentValues values) {
-        Uri result = null;
-        boolean callerIsSyncAdapter = isCallerSyncAdapter(uri);
-        boolean applyingBatch = applyingBatch();
-        if (!applyingBatch) {
-            mDb = mOpenHelper.getWritableDatabase();
-            mDb.beginTransaction();
-            try {
-                result = insertInTransaction(uri, values, callerIsSyncAdapter);
-                mDb.setTransactionSuccessful();
-            } finally {
-                mDb.endTransaction();
-            }
-
-            onEndTransaction(callerIsSyncAdapter);
-        } else {
-            result = insertInTransaction(uri, values, callerIsSyncAdapter);
-        }
-        return result;
-    }
-
-    @Override
-    public int bulkInsert(Uri uri, ContentValues[] values) {
-        int numValues = values.length;
-        boolean callerIsSyncAdapter = isCallerSyncAdapter(uri);
-        mDb = mOpenHelper.getWritableDatabase();
-        mDb.beginTransaction();
-        try {
-            for (int i = 0; i < numValues; i++) {
-                Uri result = insertInTransaction(uri, values[i], callerIsSyncAdapter);
-                mDb.yieldIfContendedSafely();
-            }
-            mDb.setTransactionSuccessful();
-        } finally {
-            mDb.endTransaction();
-        }
-
-        onEndTransaction(callerIsSyncAdapter);
-        return numValues;
-    }
-
-    @Override
-    public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
-        int count = 0;
-        boolean callerIsSyncAdapter = isCallerSyncAdapter(uri);
-        boolean applyingBatch = applyingBatch();
-        if (!applyingBatch) {
-            mDb = mOpenHelper.getWritableDatabase();
-            mDb.beginTransaction();
-            try {
-                count = updateInTransaction(uri, values, selection, selectionArgs,
-                        callerIsSyncAdapter);
-                mDb.setTransactionSuccessful();
-            } finally {
-                mDb.endTransaction();
-            }
-
-            onEndTransaction(callerIsSyncAdapter);
-        } else {
-            count = updateInTransaction(uri, values, selection, selectionArgs, callerIsSyncAdapter);
-        }
-
-        return count;
-    }
-
-    @Override
-    public int delete(Uri uri, String selection, String[] selectionArgs) {
-        int count = 0;
-        boolean callerIsSyncAdapter = isCallerSyncAdapter(uri);
-        boolean applyingBatch = applyingBatch();
-        if (!applyingBatch) {
-            mDb = mOpenHelper.getWritableDatabase();
-            mDb.beginTransaction();
-            try {
-                count = deleteInTransaction(uri, selection, selectionArgs, callerIsSyncAdapter);
-                mDb.setTransactionSuccessful();
-            } finally {
-                mDb.endTransaction();
-            }
-
-            onEndTransaction(callerIsSyncAdapter);
-        } else {
-            count = deleteInTransaction(uri, selection, selectionArgs, callerIsSyncAdapter);
-        }
-        return count;
-    }
-
-    @Override
-    public ContentProviderResult[] applyBatch(ArrayList<ContentProviderOperation> operations)
-            throws OperationApplicationException {
-        int ypCount = 0;
-        int opCount = 0;
-        boolean callerIsSyncAdapter = false;
-        mDb = mOpenHelper.getWritableDatabase();
-        mDb.beginTransaction();
-        try {
-            mApplyingBatch.set(true);
-            final int numOperations = operations.size();
-            final ContentProviderResult[] results = new ContentProviderResult[numOperations];
-            for (int i = 0; i < numOperations; i++) {
-                if (++opCount >= MAX_OPERATIONS_PER_YIELD_POINT) {
-                    throw new OperationApplicationException(
-                            "Too many content provider operations between yield points. "
-                                    + "The maximum number of operations per yield point is "
-                                    + MAX_OPERATIONS_PER_YIELD_POINT, ypCount);
-                }
-                final ContentProviderOperation operation = operations.get(i);
-                if (!callerIsSyncAdapter && isCallerSyncAdapter(operation.getUri())) {
-                    callerIsSyncAdapter = true;
-                }
-                if (i > 0 && operation.isYieldAllowed()) {
-                    opCount = 0;
-                    if (mDb.yieldIfContendedSafely(SLEEP_AFTER_YIELD_DELAY)) {
-                        ypCount++;
-                    }
-                }
-                results[i] = operation.apply(this, results, i);
-            }
-            mDb.setTransactionSuccessful();
-            return results;
-        } finally {
-            mApplyingBatch.set(false);
-            mDb.endTransaction();
-            onEndTransaction(callerIsSyncAdapter);
-        }
-    }
-
-    protected void onEndTransaction(boolean callerIsSyncAdapter) {
-        Set<Uri> changed;
-        synchronized (mChangedUris) {
-            changed = new HashSet<Uri>(mChangedUris);
-            mChangedUris.clear();
-        }
-        ContentResolver resolver = getContext().getContentResolver();
-        for (Uri uri : changed) {
-            boolean syncToNetwork = !callerIsSyncAdapter && syncToNetwork(uri);
-            resolver.notifyChange(uri, null, syncToNetwork);
-        }
-    }
-
-    protected boolean syncToNetwork(Uri uri) {
-        return false;
-    }
-}
diff --git a/tests/Android.mk b/tests/Android.mk
deleted file mode 100644
index 61f6a2a..0000000
--- a/tests/Android.mk
+++ /dev/null
@@ -1,35 +0,0 @@
-# Copyright 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.
-
-LOCAL_PATH:= $(call my-dir)
-include $(CLEAR_VARS)
-
-# We only want this apk build for tests.
-LOCAL_MODULE_TAGS := tests
-
-LOCAL_JAVA_LIBRARIES := android.test.runner
-
-# Include all test java files.
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-
-# Notice that we don't have to include the src files of BookmarkProvider
-# because, by running the tests using an instrumentation targeting
-# BookmarkProvider, we automatically get all of its classes loaded into our
-# environment.
-
-LOCAL_PACKAGE_NAME := BookmarkProviderTests
-
-LOCAL_INSTRUMENTATION_FOR := BookmarkProvider
-
-include $(BUILD_PACKAGE)
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
deleted file mode 100644
index c0583fe..0000000
--- a/tests/AndroidManifest.xml
+++ /dev/null
@@ -1,37 +0,0 @@
-<?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.
--->
-
-<!-- package name must be unique so suffix with "tests" so package loader doesn't ignore us -->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.android.bookmarkprovider.tests">
-
-    <!-- We add an application tag here just so that we can indicate that
-         this package needs to link against the android.test library,
-         which is needed when building test cases. -->
-    <application>
-        <uses-library android:name="android.test.runner" />
-    </application>
-
-    <!--
-    This declares that this app uses the instrumentation test runner targeting
-    the package of com.android.email. To run the tests use the command:
-    "adb shell am instrument -w com.android.bookmarkprovider.tests/android.test.InstrumentationTestRunner"
-    -->
-    <instrumentation android:name="android.test.InstrumentationTestRunner"
-                     android:targetPackage="com.android.bookmarkprovider"
-                     android:label="Tests for BookmarkProvider." />
-
-</manifest>
diff --git a/tests/src/com/android/bookmarkstore/BrowserProviderTests.java b/tests/src/com/android/bookmarkstore/BrowserProviderTests.java
deleted file mode 100644
index e746890..0000000
--- a/tests/src/com/android/bookmarkstore/BrowserProviderTests.java
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * Copyright (C) 2010 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.bookmarkprovider;
-
-import com.android.bookmarkprovider.BookmarkProvider;
-import com.android.bookmarkprovider.tests.utils.ProviderTestCase3;
-
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-import android.provider.BrowserContract;
-import android.provider.BrowserContract.Bookmarks;
-import android.test.suitebuilder.annotation.MediumTest;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-
-/**
- * Unit tests for {@link BookmarkProvider}.
- */
-@MediumTest
-public class BrowserProviderTests extends ProviderTestCase3<BookmarkProvider> {
-
-    private ArrayList<Uri> mDeleteUris;
-
-    public BrowserProviderTests() {
-        super(BookmarkProvider.class,
-                BrowserContract.AUTHORITY, BookmarkProvider.LEGACY_AUTHORITY);
-    }
-
-    @Override
-    protected void setUp() throws Exception {
-        mDeleteUris = new ArrayList<Uri>();
-        super.setUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        for (Uri uri : mDeleteUris) {
-            deleteUri(uri);
-        }
-        super.tearDown();
-    }
-
-    public void testHasDefaultBookmarks() {
-        Cursor c = getBookmarksByPrefix("");
-        try {
-            assertTrue("No default bookmarks", c.getCount() > 0);
-        } finally {
-            c.close();
-        }
-    }
-
-    public void testPartialFirstTitleWord() {
-        assertInsertQuery("http://www.example.com/rasdfe", "nfgjra sdfywe", "nfgj");
-    }
-
-    public void testFullFirstTitleWord() {
-        assertInsertQuery("http://www.example.com/", "nfgjra dfger", "nfgjra");
-    }
-
-    public void testFullFirstTitleWordPartialSecond() {
-        assertInsertQuery("http://www.example.com/", "nfgjra dfger", "nfgjra df");
-    }
-
-    public void testFullTitle() {
-        assertInsertQuery("http://www.example.com/", "nfgjra dfger", "nfgjra dfger");
-    }
-
-    public void testFullTitleJapanese() {
-        String title = "\u30ae\u30e3\u30e9\u30ea\u30fc\u30fcGoogle\u691c\u7d22";
-        assertInsertQuery("http://www.example.com/sdaga", title, title);
-    }
-
-    public void testPartialTitleJapanese() {
-        String title = "\u30ae\u30e3\u30e9\u30ea\u30fc\u30fcGoogle\u691c\u7d22";
-        String query = "\u30ae\u30e3\u30e9\u30ea\u30fc";
-        assertInsertQuery("http://www.example.com/sdaga", title, query);
-    }
-
-    //
-    // Utilities
-    //
-
-    private void assertInsertQuery(String url, String title, String query) {
-        addBookmark(url, title);
-        assertQueryReturns(url, title, query);
-    }
-
-    private void assertQueryReturns(String url, String title, String query) {
-        Cursor c = getBookmarksByPrefix(query);
-        try {
-            assertTrue(title + " not matched by " + query, c.getCount() > 0);
-            assertTrue("More than one result for " + query, c.getCount() == 1);
-            while (c.moveToNext()) {
-                String gotUrl = getCol(c, Bookmarks.URL);
-                assertNotNull(gotUrl);
-                assertEquals("Bad URL", url, gotUrl);
-
-                String gotTitle = getCol(c, Bookmarks.TITLE);
-                assertNotNull(gotTitle);
-                assertEquals("Bad title", title, gotTitle);
-            }
-        } finally {
-            c.close();
-        }
-    }
-
-    private Cursor getBookmarksByPrefix(String query) {
-        Uri suggestUri = Uri.parse("content://browser/bookmarks");
-        String[] selectionArgs = { query + "%" };
-        Cursor c = getMockContentResolver().query(suggestUri, null, "title LIKE ?",
-                selectionArgs, null);
-        assertNotNull(c);
-        return c;
-    }
-
-    private void addBookmark(String url, String title) {
-        Uri uri = insertBookmark(url, title);
-        assertNotNull(uri);
-        assertFalse(android.provider.Browser.BOOKMARKS_URI.equals(uri));
-        mDeleteUris.add(uri);
-    }
-
-    private Uri insertBookmark(String url, String title) {
-        ContentValues values = new ContentValues();
-        values.put("title", title);
-        values.put("url", url);
-        values.put("visits", 0);
-        values.put("date", 0);
-        values.put("created", 0);
-        values.put("bookmark", 1);
-        return getMockContentResolver().insert(android.provider.Browser.BOOKMARKS_URI,
-                values);
-    }
-
-    private void deleteUri(Uri uri) {
-        int count = getMockContentResolver().delete(uri, null, null);
-        assertEquals("Failed to delete " + uri, 1, count);
-    }
-
-    private static String getCol(Cursor c, String name) {
-        int col = c.getColumnIndex(name);
-        String msg = "Column " + name + " not found, columns: "
-                + Arrays.toString(c.getColumnNames());
-        assertTrue(msg, col >= 0);
-        return c.getString(col);
-    }
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/BP2ProviderTests.java b/tests/src/com/android/bookmarkstore/tests/BP2ProviderTests.java
deleted file mode 100644
index ff31109..0000000
--- a/tests/src/com/android/bookmarkstore/tests/BP2ProviderTests.java
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests;
-
-import com.android.bookmarkprovider.tests.utils.BP2TestCaseHelper;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.graphics.Bitmap;
-import android.graphics.Bitmap.Config;
-import android.net.Uri;
-import android.provider.BrowserContract;
-import android.provider.BrowserContract.Images;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.ByteArrayOutputStream;
-
-@SmallTest
-public class BP2ProviderTests extends BP2TestCaseHelper {
-
-    static final String[] PROJECTION = new String[] {
-            BrowserContract.Bookmarks.PARENT,
-            BrowserContract.Bookmarks.ACCOUNT_NAME,
-            BrowserContract.Bookmarks.ACCOUNT_TYPE,
-    };
-    static final int INDEX_PARENT = 0;
-    static final int INDEX_ACCOUNT_NAME = 1;
-    static final int INDEX_ACCOUNT_TYPE = 2;
-
-    public void testUpdateImage() {
-        String url = "http://stub1.com";
-        insertBookmark(url, "stub 1");
-        ContentValues values = new ContentValues();
-        values.put(Images.URL, url);
-        Bitmap bitmap = Bitmap.createBitmap(1, 1, Config.ARGB_8888);
-        ByteArrayOutputStream os = new ByteArrayOutputStream();
-        bitmap.compress(Bitmap.CompressFormat.PNG, 100, os);
-        values.put(Images.THUMBNAIL, os.toByteArray());
-        // Use updateBookmarks because the bookmarks URI observer should
-        // be triggered, even though we aren't giving it a bookmarks URI
-        assertTrue(updateBookmark(Images.CONTENT_URI, values));
-    }
-
-    public void testIsValidParentNullAccount() {
-        doTestIsValidParent(null, null);
-    }
-
-    public void testIsValidParentWithAccount() {
-        doTestIsValidParent("test@gmail.com", "com.google");
-    }
-
-    private void doTestIsValidParent(String accountName, String accountType) {
-        // Create the folder
-        ContentValues values = new ContentValues();
-        values.put(BrowserContract.Bookmarks.TITLE, "New Folder");
-        values.put(BrowserContract.Bookmarks.IS_FOLDER, 1);
-        values.put(BrowserContract.Bookmarks.ACCOUNT_NAME, accountName);
-        values.put(BrowserContract.Bookmarks.ACCOUNT_TYPE, accountType);
-        Uri folderUri = insertBookmark(values);
-        assertNotNull(folderUri);
-        long folderId = ContentUris.parseId(folderUri);
-        assertTrue("Failed to parse folder id!", folderId > 0);
-        // Insert a bookmark with the same ACCOUNT_* info as parent
-        values.put(BrowserContract.Bookmarks.TITLE, "google");
-        values.put(BrowserContract.Bookmarks.URL, "http://google.com");
-        values.put(BrowserContract.Bookmarks.IS_FOLDER, 0);
-        values.put(BrowserContract.Bookmarks.PARENT, folderId);
-        Uri insertedUri = insertBookmark(values);
-        assertNotNull(insertedUri);
-        Cursor c = getMockContentResolver().query(insertedUri,
-                PROJECTION, null, null, null);
-        try {
-            assertNotNull(c);
-            assertTrue(c.moveToFirst());
-            long insertedParentId = c.getLong(INDEX_PARENT);
-            String insertedAccountName = c.getString(INDEX_ACCOUNT_NAME);
-            String insertedAccountType = c.getString(INDEX_ACCOUNT_TYPE);
-            assertEquals(folderId, insertedParentId);
-            assertEquals(accountName, insertedAccountName);
-            assertEquals(accountType, insertedAccountType);
-
-            // Insert a bookmark with no ACCOUNT_* set, BUT with a valid parent
-            // The inserted should end up with the ACCOUNT_* of the parent
-            values.remove(BrowserContract.Bookmarks.ACCOUNT_NAME);
-            values.remove(BrowserContract.Bookmarks.ACCOUNT_TYPE);
-            insertedUri = insertBookmark(values);
-            assertNotNull(insertedUri);
-            c.close();
-            c = getMockContentResolver().query(insertedUri,
-                    PROJECTION, null, null, null);
-            assertNotNull(c);
-            assertTrue(c.moveToFirst());
-            insertedParentId = c.getLong(INDEX_PARENT);
-            insertedAccountName = c.getString(INDEX_ACCOUNT_NAME);
-            insertedAccountType = c.getString(INDEX_ACCOUNT_TYPE);
-            assertEquals(folderId, insertedParentId);
-            assertEquals(accountName, insertedAccountName);
-            assertEquals(accountType, insertedAccountType);
-
-            // Insert a bookmark with a different ACCOUNT_* than it's parent
-            // ACCOUNT_* should override parent
-            accountName = accountName + "@something.else";
-            accountType = "com.google";
-            values.put(BrowserContract.Bookmarks.ACCOUNT_NAME, accountName);
-            values.put(BrowserContract.Bookmarks.ACCOUNT_TYPE, accountType);
-            insertedUri = insertBookmark(values);
-            assertNotNull(insertedUri);
-            c.close();
-            c = getMockContentResolver().query(insertedUri,
-                    PROJECTION, null, null, null);
-            assertNotNull(c);
-            assertTrue(c.moveToFirst());
-            insertedParentId = c.getLong(INDEX_PARENT);
-            insertedAccountName = c.getString(INDEX_ACCOUNT_NAME);
-            insertedAccountType = c.getString(INDEX_ACCOUNT_TYPE);
-            assertNotSame(folderId, insertedParentId);
-            assertEquals(accountName, insertedAccountName);
-            assertEquals(accountType, insertedAccountType);
-        } finally {
-            c.close();
-        }
-    }
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/BookmarksTests.java b/tests/src/com/android/bookmarkstore/tests/BookmarksTests.java
deleted file mode 100644
index e6a6b90..0000000
--- a/tests/src/com/android/bookmarkstore/tests/BookmarksTests.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests;
-
-import com.android.bookmarkprovider.tests.utils.BP2TestCaseHelper;
-
-import android.content.ContentResolver;
-import android.database.Cursor;
-import android.provider.BrowserContract.Combined;
-import android.test.suitebuilder.annotation.SmallTest;
-
-/**
- * Extends from BP2TestCaseHelper for the helper methods
- * and to get the mock database
- */
-@SmallTest
-public class BookmarksTests extends BP2TestCaseHelper {
-    private static final String QUERY_BOOKMARKS_WHERE =
-            Combined.URL + " == ? OR " +
-            Combined.URL + " == ?";
-
-    private static Cursor queryCombinedForUrl(ContentResolver cr,
-            String originalUrl, String url) {
-        if (cr == null || url == null) {
-            return null;
-        }
-
-        // If originalUrl is null, just set it to url.
-        if (originalUrl == null) {
-            originalUrl = url;
-        }
-
-        // Look for both the original url and the actual url. This takes in to
-        // account redirects.
-
-        final String[] selArgs = new String[] { originalUrl, url };
-        final String[] projection = new String[] { Combined.URL };
-        return cr.query(Combined.CONTENT_URI, projection, QUERY_BOOKMARKS_WHERE, selArgs, null);
-    }
-
-    public void testQueryCombinedForUrl() {
-        // First, add some bookmarks
-        assertNotNull(insertBookmark(
-                "http://google.com/search?q=test", "Test search"));
-        assertNotNull(insertBookmark(
-                "http://google.com/search?q=mustang", "Mustang search"));
-        assertNotNull(insertBookmark(
-                "http://google.com/search?q=aliens", "Aliens search"));
-        ContentResolver cr = getMockContentResolver();
-
-        Cursor c = null;
-        try {
-            // First, search for a match
-            String url = "http://google.com/search?q=test";
-            c = queryCombinedForUrl(cr, null, url);
-            assertEquals(1, c.getCount());
-            assertTrue(c.moveToFirst());
-            assertEquals(url, c.getString(0));
-            c.close();
-
-            // Next, search for no match
-            url = "http://google.com/search";
-            c = queryCombinedForUrl(cr, null, url);
-            assertEquals(0, c.getCount());
-            assertFalse(c.moveToFirst());
-            c.close();
-        } finally {
-            if (c != null) c.close();
-        }
-    }
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/utils/BP2TestCaseHelper.java b/tests/src/com/android/bookmarkstore/tests/utils/BP2TestCaseHelper.java
deleted file mode 100644
index 57ce669..0000000
--- a/tests/src/com/android/bookmarkstore/tests/utils/BP2TestCaseHelper.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests.utils;
-
-import com.android.bookmarkprovider.BookmarkProvider;
-
-import java.io.File;
-import java.io.FilenameFilter;
-
-import android.content.ContentValues;
-import android.net.Uri;
-import android.provider.BrowserContract;
-import android.provider.BrowserContract.Bookmarks;
-
-/**
- *  This is a replacement for ProviderTestCase2 that can handle notifyChange testing.
- *  It also has helper methods specifically for testing BookmarkProvider
- */
-public abstract class BP2TestCaseHelper extends ProviderTestCase3<BookmarkProvider> {
-
-    // Tag for potential performance impacts
-    private static final String PERFTAG = "BP2-PerfCheck";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-    }
-
-    public BP2TestCaseHelper() {
-        super(BookmarkProvider.class,
-                BrowserContract.AUTHORITY, BookmarkProvider.LEGACY_AUTHORITY);
-    }
-
-    Uri mockInsert(Uri uri, ContentValues values) {
-        return getMockContentResolver().insert(uri, values);
-    }
-
-    int mockUpdate(Uri uri, ContentValues values, String where,
-            String[] selectionArgs) {
-        return getMockContentResolver().update(uri, values, where, selectionArgs);
-    }
-
-    public Uri insertBookmark(String url, String title) {
-        ContentValues values = new ContentValues();
-        values.put(BrowserContract.Bookmarks.TITLE, title);
-        values.put(BrowserContract.Bookmarks.URL, url);
-        values.put(BrowserContract.Bookmarks.IS_FOLDER, 0);
-        return insertBookmark(values);
-    }
-
-    public Uri insertBookmark(ContentValues values) {
-        return mockInsert(Bookmarks.CONTENT_URI, values);
-    }
-
-    public boolean updateBookmark(Uri uri, String url, String title) {
-        ContentValues values = new ContentValues();
-        values.put(BrowserContract.Bookmarks.TITLE, title);
-        values.put(BrowserContract.Bookmarks.URL, url);
-        return updateBookmark(uri, values);
-    }
-
-    public boolean updateBookmark(Uri uri, ContentValues values) {
-        int modifyCount = mockUpdate(uri, values, null, null);
-        assertTrue("UpdatedBookmark modified too much! " + uri, modifyCount <= 1);
-        return modifyCount == 1;
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-        // Delete the test databases so that subsequent runs have a clean slate
-        File f = getMockContext().getDatabasePath("test");
-        File dir = f.getParentFile();
-        File testFiles[] = dir.listFiles(new FilenameFilter() {
-
-            @Override
-            public boolean accept(File dir, String filename) {
-                return filename.startsWith(ProviderTestCase3.FILENAME_PREFIX);
-            }
-        });
-        for (File testFile : testFiles) {
-            testFile.delete();
-        }
-    }
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/utils/MockContentResolver2.java b/tests/src/com/android/bookmarkstore/tests/utils/MockContentResolver2.java
deleted file mode 100644
index 2d91425..0000000
--- a/tests/src/com/android/bookmarkstore/tests/utils/MockContentResolver2.java
+++ /dev/null
@@ -1,115 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests.utils;
-
-import com.google.android.collect.Maps;
-
-import android.content.ContentProvider;
-import android.content.ContentResolver;
-import android.content.Context;
-import android.content.IContentProvider;
-import android.database.ContentObserver;
-import android.net.Uri;
-
-import java.util.Map;
-
-public class MockContentResolver2 extends ContentResolver {
-
-    Map<String, ContentProvider> mProviders;
-    private final MockObserverNode mRootNode = new MockObserverNode("");
-
-    /*
-     * Creates a local map of providers. This map is used instead of the global map when an
-     * API call tries to acquire a provider.
-     */
-    public MockContentResolver2() {
-        super(null);
-        mProviders = Maps.newHashMap();
-    }
-
-    /**
-     * Adds access to a provider based on its authority
-     *
-     * @param name The authority name associated with the provider.
-     * @param provider An instance of {@link android.content.ContentProvider} or one of its
-     * subclasses, or null.
-     */
-    public void addProvider(String name, ContentProvider provider) {
-        /*
-         * Maps the authority to the provider locally.
-         */
-        mProviders.put(name, provider);
-    }
-
-    /** @hide */
-    @Override
-    protected IContentProvider acquireProvider(Context context, String name) {
-        return acquireExistingProvider(context, name);
-    }
-
-    /** @hide */
-    @Override
-    protected IContentProvider acquireExistingProvider(Context context, String name) {
-
-        /*
-         * Gets the content provider from the local map
-         */
-        final ContentProvider provider = mProviders.get(name);
-
-        if (provider != null) {
-            return provider.getIContentProvider();
-        } else {
-            return null;
-        }
-    }
-
-    /** @hide */
-    @Override
-    public boolean releaseProvider(IContentProvider provider) {
-        return true;
-    }
-
-    /** @hide */
-    protected IContentProvider acquireUnstableProvider(Context c, String name) {
-        return acquireProvider(c, name);
-    }
-
-    /** @hide */
-    public boolean releaseUnstableProvider(IContentProvider icp) {
-        return releaseProvider(icp);
-    }
-
-    /** @hide */
-    public void unstableProviderDied(IContentProvider icp) {
-    }
-
-    @Override
-    public void notifyChange(Uri uri, ContentObserver observer,
-            boolean syncToNetwork) {
-        mRootNode.notifyMyObservers(uri, 0, observer, false);
-    }
-
-    public void safeRegisterContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        mRootNode.addObserver(uri, observer, notifyForDescendents);
-    }
-
-    public void safeUnregisterContentObserver(ContentObserver observer) {
-        mRootNode.removeObserver(observer);
-    }
-
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/utils/MockObserverNode.java b/tests/src/com/android/bookmarkstore/tests/utils/MockObserverNode.java
deleted file mode 100644
index 996b3b3..0000000
--- a/tests/src/com/android/bookmarkstore/tests/utils/MockObserverNode.java
+++ /dev/null
@@ -1,169 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests.utils;
-
-import android.database.ContentObserver;
-import android.net.Uri;
-
-import java.util.ArrayList;
-
-public final class MockObserverNode {
-    private class MockObserverEntry {
-        public final ContentObserver observer;
-        public final boolean notifyForDescendents;
-
-        public MockObserverEntry(ContentObserver o, boolean n) {
-            observer = o;
-            notifyForDescendents = n;
-        }
-    }
-
-    public static final int INSERT_TYPE = 0;
-    public static final int UPDATE_TYPE = 1;
-    public static final int DELETE_TYPE = 2;
-
-    private String mName;
-    private ArrayList<MockObserverNode> mChildren = new ArrayList<MockObserverNode>();
-    private ArrayList<MockObserverEntry> mObservers = new ArrayList<MockObserverEntry>();
-
-    public MockObserverNode(String name) {
-        mName = name;
-    }
-
-    private String getUriSegment(Uri uri, int index) {
-        if (uri != null) {
-            if (index == 0) {
-                return uri.getAuthority();
-            } else {
-                return uri.getPathSegments().get(index - 1);
-            }
-        } else {
-            return null;
-        }
-    }
-
-    private int countUriSegments(Uri uri) {
-        if (uri == null) {
-            return 0;
-        }
-        return uri.getPathSegments().size() + 1;
-    }
-
-    public void addObserver(Uri uri, ContentObserver observer,
-            boolean notifyForDescendents) {
-        addObserver(uri, 0, observer, notifyForDescendents);
-    }
-
-    private void addObserver(Uri uri, int index, ContentObserver observer,
-            boolean notifyForDescendents) {
-        // If this is the leaf node add the observer
-        if (index == countUriSegments(uri)) {
-            mObservers.add(new MockObserverEntry(observer, notifyForDescendents));
-            return;
-        }
-
-        // Look to see if the proper child already exists
-        String segment = getUriSegment(uri, index);
-        if (segment == null) {
-            throw new IllegalArgumentException("Invalid Uri (" + uri + ") used for observer");
-        }
-        int N = mChildren.size();
-        for (int i = 0; i < N; i++) {
-            MockObserverNode node = mChildren.get(i);
-            if (node.mName.equals(segment)) {
-                node.addObserver(uri, index + 1, observer, notifyForDescendents);
-                return;
-            }
-        }
-
-        // No child found, create one
-        MockObserverNode node = new MockObserverNode(segment);
-        mChildren.add(node);
-        node.addObserver(uri, index + 1, observer, notifyForDescendents);
-    }
-
-    public boolean removeObserver(ContentObserver observer) {
-        int size = mChildren.size();
-        for (int i = 0; i < size; i++) {
-            boolean empty = mChildren.get(i).removeObserver(observer);
-            if (empty) {
-                mChildren.remove(i);
-                i--;
-                size--;
-            }
-        }
-
-        size = mObservers.size();
-        for (int i = 0; i < size; i++) {
-            MockObserverEntry entry = mObservers.get(i);
-            if (entry.observer == observer) {
-                mObservers.remove(i);
-                break;
-            }
-        }
-
-        if (mChildren.size() == 0 && mObservers.size() == 0) {
-            return true;
-        }
-        return false;
-    }
-
-    private void notifyMyObservers(boolean leaf, ContentObserver observer,
-            boolean selfNotify) {
-        int N = mObservers.size();
-        for (int i = 0; i < N; i++) {
-            MockObserverEntry entry = mObservers.get(i);
-
-            // Don't notify the observer if it sent the notification and isn't interesed
-            // in self notifications
-            if (entry.observer == observer && !selfNotify) {
-                continue;
-            }
-
-            // Make sure the observer is interested in the notification
-            if (leaf || (!leaf && entry.notifyForDescendents)) {
-                entry.observer.onChange(selfNotify);
-            }
-        }
-    }
-
-    public void notifyMyObservers(Uri uri, int index, ContentObserver observer,
-            boolean selfNotify) {
-        String segment = null;
-        int segmentCount = countUriSegments(uri);
-        if (index >= segmentCount) {
-            // This is the leaf node, notify all observers
-            notifyMyObservers(true, observer, selfNotify);
-        } else if (index < segmentCount){
-            segment = getUriSegment(uri, index);
-            // Notify any observers at this level who are interested in descendents
-            notifyMyObservers(false, observer, selfNotify);
-        }
-
-        int N = mChildren.size();
-        for (int i = 0; i < N; i++) {
-            MockObserverNode node = mChildren.get(i);
-            if (segment == null || node.mName.equals(segment)) {
-                // We found the child,
-                node.notifyMyObservers(uri, index + 1, observer, selfNotify);
-                if (segment != null) {
-                    break;
-                }
-            }
-        }
-    }
-}
diff --git a/tests/src/com/android/bookmarkstore/tests/utils/ProviderTestCase3.java b/tests/src/com/android/bookmarkstore/tests/utils/ProviderTestCase3.java
deleted file mode 100644
index f8eb161..0000000
--- a/tests/src/com/android/bookmarkstore/tests/utils/ProviderTestCase3.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * Copyright (C) 2011 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.bookmarkprovider.tests.utils;
-
-import android.content.ContentProvider;
-import android.content.Context;
-import android.content.SharedPreferences;
-import android.content.res.Resources;
-import android.database.ContentObserver;
-import android.net.Uri;
-import android.test.AndroidTestCase;
-import android.test.IsolatedContext;
-import android.test.RenamingDelegatingContext;
-import android.test.mock.MockContext;
-
-import java.io.File;
-
-import android.content.pm.ProviderInfo;
-
-/**
- * Replacement for ProviderTestCase2 that keeps calls to ContentResolver.notifyChanged
- * internal to observers registered with ProviderTestCase3.registerContentObserver
- */
-public abstract class ProviderTestCase3<T extends ContentProvider> extends AndroidTestCase {
-
-    public static final String FILENAME_PREFIX = "test.";
-
-    private static final String BROWSER_AUTHORITIES = "com.android.browser;browser";
-
-    Class<T> mProviderClass;
-    String[] mProviderAuthority;
-
-    private IsolatedContext mProviderContext;
-    private MockContentResolver2 mResolver;
-
-    private class MockContext2 extends MockContext {
-
-        @Override
-        public Resources getResources() {
-            return getContext().getResources();
-        }
-
-        @Override
-        public File getDir(String name, int mode) {
-            // name the directory so the directory will be separated from
-            // one created through the regular Context
-            return getContext().getDir("mockcontext2_" + name, mode);
-        }
-
-        @Override
-        public String getPackageName() {
-            return getContext().getPackageName();
-        }
-
-        @Override
-        public SharedPreferences getSharedPreferences(String name, int mode) {
-            return getContext().getSharedPreferences("mockcontext2_" + name, mode);
-        }
-
-        @Override
-        public Context getApplicationContext() {
-            return this;
-        }
-
-        @Override
-        public Object getSystemService(String name) {
-            return null;
-        }
-    }
-    /**
-     * Constructor.
-     *
-     * @param providerClass The class name of the provider under test
-     * @param providerAuthorities The provider's authority string
-     */
-    public ProviderTestCase3(Class<T> providerClass, String... providerAuthorities) {
-        mProviderClass = providerClass;
-        mProviderAuthority = providerAuthorities;
-    }
-
-    private T mProvider;
-
-    /**
-     * Returns the content provider created by this class in the {@link #setUp()} method.
-     * @return T An instance of the provider class given as a parameter to the test case class.
-     */
-    public T getProvider() {
-        return mProvider;
-    }
-
-    /**
-     * Sets up the environment for the test fixture.
-     * <p>
-     * Creates a new
-     * {@link com.android.bookmarkprovider.tests.utils.MockContentResolver2}, a new IsolatedContext
-     * that isolates the provider's file operations, and a new instance of
-     * the provider under test within the isolated environment.
-     * </p>
-     *
-     * @throws Exception
-     */
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        mResolver = new MockContentResolver2();
-        RenamingDelegatingContext targetContextWrapper = new
-                RenamingDelegatingContext(
-                new MockContext2(), // The context that most methods are
-                                    //delegated to
-                getContext(), // The context that file methods are delegated to
-                FILENAME_PREFIX);
-        // The default IsolatedContext has a mock AccountManager that doesn't
-        // work for us, so override getSystemService to always return null
-        mProviderContext = new IsolatedContext(mResolver, targetContextWrapper) {
-
-            @Override
-            public Object getSystemService(String name) {
-                return null;
-            }
-        };
-
-        mProvider = mProviderClass.newInstance();
-        ProviderInfo info = new ProviderInfo();
-        info.authority = BROWSER_AUTHORITIES;
-        mProvider.attachInfoForTesting(mProviderContext, info);
-        assertNotNull(mProvider);
-        for (String auth : mProviderAuthority) {
-            mResolver.addProvider(auth, getProvider());
-        }
-    }
-
-    /**
-     * Tears down the environment for the test fixture.
-     * <p>
-     * Calls {@link android.content.ContentProvider#shutdown()} on the
-     * {@link android.content.ContentProvider} represented by mProvider.
-     */
-    @Override
-    protected void tearDown() throws Exception {
-        mProvider.shutdown();
-        super.tearDown();
-    }
-
-    /**
-     * Gets the {@link MockContentResolver2} created by this class during initialization. You
-     * must use the methods of this resolver to access the provider under test.
-     *
-     * @return A {@link MockContentResolver2} instance.
-     */
-    public MockContentResolver2 getMockContentResolver() {
-        return mResolver;
-    }
-
-    /**
-     * Gets the {@link IsolatedContext} created by this class during initialization.
-     * @return The {@link IsolatedContext} instance
-     */
-    public IsolatedContext getMockContext() {
-        return mProviderContext;
-    }
-
-    public void registerContentObserver(Uri uri, boolean notifyForDescendents,
-            ContentObserver observer) {
-        mResolver.safeRegisterContentObserver(uri, notifyForDescendents, observer);
-    }
-
-    public void unregisterContentObserver(ContentObserver observer) {
-        mResolver.safeUnregisterContentObserver(observer);
-    }
-
-}
