diff --git a/api/current.txt b/api/current.txt
index fa2a475..971db1d 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1992,10 +1992,11 @@
     method public static java.lang.String feedbackTypeToString(int);
     method public static java.lang.String flagToString(int);
     method public boolean getCanRetrieveWindowContent();
-    method public java.lang.String getDescription();
+    method public deprecated java.lang.String getDescription();
     method public java.lang.String getId();
     method public android.content.pm.ResolveInfo getResolveInfo();
     method public java.lang.String getSettingsActivityName();
+    method public java.lang.String loadDescription(android.content.pm.PackageManager);
     method public void writeToParcel(android.os.Parcel, int);
     field public static final android.os.Parcelable.Creator CREATOR;
     field public static final int DEFAULT = 1; // 0x1
@@ -7204,7 +7205,7 @@
     method public long insertWithOnConflict(java.lang.String, java.lang.String, android.content.ContentValues, int);
     method public boolean isDatabaseIntegrityOk();
     method public boolean isDbLockedByCurrentThread();
-    method public boolean isDbLockedByOtherThreads();
+    method public deprecated boolean isDbLockedByOtherThreads();
     method public boolean isOpen();
     method public boolean isReadOnly();
     method public deprecated void markTableSyncable(java.lang.String, java.lang.String);
@@ -7226,7 +7227,7 @@
     method public long replace(java.lang.String, java.lang.String, android.content.ContentValues);
     method public long replaceOrThrow(java.lang.String, java.lang.String, android.content.ContentValues) throws android.database.SQLException;
     method public void setLocale(java.util.Locale);
-    method public void setLockingEnabled(boolean);
+    method public deprecated void setLockingEnabled(boolean);
     method public void setMaxSqlCacheSize(int);
     method public long setMaximumSize(long);
     method public void setPageSize(long);
diff --git a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
index e5a5e98..eae0a4c 100644
--- a/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
+++ b/core/java/android/accessibilityservice/AccessibilityServiceInfo.java
@@ -28,6 +28,7 @@
 import android.os.Parcel;
 import android.os.Parcelable;
 import android.util.AttributeSet;
+import android.util.TypedValue;
 import android.util.Xml;
 import android.view.accessibility.AccessibilityEvent;
 
@@ -182,9 +183,14 @@
     private boolean mCanRetrieveWindowContent;
 
     /**
-     * Description of the accessibility service.
+     * Resource id of the description of the accessibility service.
      */
-    private String mDescription;
+    private int mDescriptionResId;
+
+    /**
+     * Non localized description of the accessibility service.
+     */
+    private String mNonLocalizedDescription;
 
     /**
      * Creates a new instance.
@@ -256,8 +262,15 @@
             mCanRetrieveWindowContent = asAttributes.getBoolean(
                     com.android.internal.R.styleable.AccessibilityService_canRetrieveWindowContent,
                     false);
-            mDescription = asAttributes.getString(
+            TypedValue peekedValue = asAttributes.peekValue(
                     com.android.internal.R.styleable.AccessibilityService_description);
+            if (peekedValue != null) {
+                mDescriptionResId = peekedValue.resourceId;
+                CharSequence nonLocalizedDescription = peekedValue.coerceToString();
+                if (nonLocalizedDescription != null) {
+                    mNonLocalizedDescription = nonLocalizedDescription.toString().trim();
+                }
+            }
             asAttributes.recycle();
         } catch (NameNotFoundException e) {
             throw new XmlPullParserException( "Unable to create context for: "
@@ -331,15 +344,38 @@
     }
 
     /**
-     * Description of the accessibility service.
+     * Gets the non-localized description of the accessibility service.
      * <p>
      *    <strong>Statically set from
      *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
      * </p>
      * @return The description.
+     *
+     * @deprecated Use {@link #loadDescription(PackageManager)}.
      */
     public String getDescription() {
-        return mDescription;
+        return mNonLocalizedDescription;
+    }
+
+    /**
+     * The localized description of the accessibility service.
+     * <p>
+     *    <strong>Statically set from
+     *    {@link AccessibilityService#SERVICE_META_DATA meta-data}.</strong>
+     * </p>
+     * @return The localized description.
+     */
+    public String loadDescription(PackageManager packageManager) {
+        if (mDescriptionResId == 0) {
+            return mNonLocalizedDescription;
+        }
+        ServiceInfo serviceInfo = mResolveInfo.serviceInfo;
+        CharSequence description = packageManager.getText(serviceInfo.packageName,
+                mDescriptionResId, serviceInfo.applicationInfo);
+        if (description != null) {
+            return description.toString().trim();
+        }
+        return null;
     }
 
     /**
@@ -359,7 +395,8 @@
         parcel.writeParcelable(mResolveInfo, 0);
         parcel.writeString(mSettingsActivityName);
         parcel.writeInt(mCanRetrieveWindowContent ? 1 : 0);
-        parcel.writeString(mDescription);
+        parcel.writeInt(mDescriptionResId);
+        parcel.writeString(mNonLocalizedDescription);
     }
 
     private void initFromParcel(Parcel parcel) {
@@ -372,7 +409,8 @@
         mResolveInfo = parcel.readParcelable(null);
         mSettingsActivityName = parcel.readString();
         mCanRetrieveWindowContent = (parcel.readInt() == 1);
-        mDescription = parcel.readString();
+        mDescriptionResId = parcel.readInt();
+        mNonLocalizedDescription = parcel.readString();
     }
 
     @Override
diff --git a/core/java/android/database/CursorWindow.java b/core/java/android/database/CursorWindow.java
index e9675e8..85f570c1 100644
--- a/core/java/android/database/CursorWindow.java
+++ b/core/java/android/database/CursorWindow.java
@@ -98,8 +98,8 @@
      */
     public CursorWindow(String name) {
         mStartPos = 0;
-        mName = name;
-        mWindowPtr = nativeCreate(name, sCursorWindowSize);
+        mName = name != null && name.length() != 0 ? name : "<unnamed>";
+        mWindowPtr = nativeCreate(mName, sCursorWindowSize);
         if (mWindowPtr == 0) {
             throw new CursorWindowAllocationException("Cursor window allocation of " +
                     (sCursorWindowSize / 1024) + " kb failed. " + printStats());
@@ -161,7 +161,7 @@
     }
 
     /**
-     * Gets the name of this cursor window.
+     * Gets the name of this cursor window, never null.
      * @hide
      */
     public String getName() {
diff --git a/core/java/android/database/sqlite/DatabaseConnectionPool.java b/core/java/android/database/sqlite/DatabaseConnectionPool.java
deleted file mode 100644
index 39a9d23..0000000
--- a/core/java/android/database/sqlite/DatabaseConnectionPool.java
+++ /dev/null
@@ -1,348 +0,0 @@
-/*
- * Copyright (C) 20010 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 android.database.sqlite;
-
-import android.content.res.Resources;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.util.ArrayList;
-import java.util.HashSet;
-import java.util.Random;
-
-/**
- * A connection pool to be used by readers.
- * Note that each connection can be used by only one reader at a time.
- */
-/* package */ class DatabaseConnectionPool {
-
-    private static final String TAG = "DatabaseConnectionPool";
-
-    /** The default connection pool size. */
-    private volatile int mMaxPoolSize =
-        Resources.getSystem().getInteger(com.android.internal.R.integer.db_connection_pool_size);
-
-    /** The connection pool objects are stored in this member.
-     * TODO: revisit this data struct as the number of pooled connections increase beyond
-     * single-digit values.
-     */
-    private final ArrayList<PoolObj> mPool = new ArrayList<PoolObj>(mMaxPoolSize);
-
-    /** the main database connection to which this connection pool is attached */
-    private final SQLiteDatabase mParentDbObj;
-
-    /** Random number generator used to pick a free connection out of the pool */
-    private Random rand; // lazily initialized
-
-    /* package */ DatabaseConnectionPool(SQLiteDatabase db) {
-        this.mParentDbObj = db;
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Max Pool Size: " + mMaxPoolSize);
-        }
-    }
-
-    /**
-     * close all database connections in the pool - even if they are in use!
-     */
-    /* package */ synchronized void close() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "Closing the connection pool on " + mParentDbObj.getPath() + toString());
-        }
-        for (int i = mPool.size() - 1; i >= 0; i--) {
-            mPool.get(i).mDb.close();
-        }
-        mPool.clear();
-    }
-
-    /**
-     * get a free connection from the pool
-     *
-     * @param sql if not null, try to find a connection inthe pool which already has cached
-     * the compiled statement for this sql.
-     * @return the Database connection that the caller can use
-     */
-    /* package */ synchronized SQLiteDatabase get(String sql) {
-        SQLiteDatabase db = null;
-        PoolObj poolObj = null;
-        int poolSize = mPool.size();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            assert sql != null;
-            doAsserts();
-        }
-        if (getFreePoolSize() == 0) {
-            // no free ( = available) connections
-            if (mMaxPoolSize == poolSize) {
-                // maxed out. can't open any more connections.
-                // let the caller wait on one of the pooled connections
-                // preferably a connection caching the pre-compiled statement of the given SQL
-                if (mMaxPoolSize == 1) {
-                    poolObj = mPool.get(0);
-                } else {
-                    for (int i = 0; i < mMaxPoolSize; i++) {
-                        if (mPool.get(i).mDb.isInStatementCache(sql)) {
-                            poolObj = mPool.get(i);
-                            break;
-                        }
-                    }
-                    if (poolObj == null) {
-                        // there are no database connections with the given SQL pre-compiled.
-                        // ok to return any of the connections.
-                        if (rand == null) {
-                            rand = new Random(SystemClock.elapsedRealtime());
-                        }
-                        poolObj = mPool.get(rand.nextInt(mMaxPoolSize));
-                    }
-                }
-                db = poolObj.mDb;
-            } else {
-                // create a new connection and add it to the pool, since we haven't reached
-                // max pool size allowed
-                db = mParentDbObj.createPoolConnection((short)(poolSize + 1));
-                poolObj = new PoolObj(db);
-                mPool.add(poolSize, poolObj);
-            }
-        } else {
-            // there are free connections available. pick one
-            // preferably a connection caching the pre-compiled statement of the given SQL
-            for (int i = 0; i < poolSize; i++) {
-                if (mPool.get(i).isFree() && mPool.get(i).mDb.isInStatementCache(sql)) {
-                    poolObj = mPool.get(i);
-                    break;
-                }
-            }
-            if (poolObj == null) {
-                // didn't find a free database connection with the given SQL already
-                // pre-compiled. return a free connection (this means, the same SQL could be
-                // pre-compiled on more than one database connection. potential wasted memory.)
-                for (int i = 0; i < poolSize; i++) {
-                    if (mPool.get(i).isFree()) {
-                        poolObj = mPool.get(i);
-                        break;
-                    }
-                }
-            }
-            db = poolObj.mDb;
-        }
-
-        assert poolObj != null;
-        assert poolObj.mDb == db;
-
-        poolObj.acquire();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "END get-connection: " + toString() + poolObj.toString());
-        }
-        return db;
-        // TODO if a thread acquires a connection and dies without releasing the connection, then
-        // there could be a connection leak.
-    }
-
-    /**
-     * release the given database connection back to the pool.
-     * @param db the connection to be released
-     */
-    /* package */ synchronized void release(SQLiteDatabase db) {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            assert db.mConnectionNum > 0;
-            doAsserts();
-            assert mPool.get(db.mConnectionNum - 1).mDb == db;
-        }
-
-        PoolObj poolObj = mPool.get(db.mConnectionNum - 1);
-
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "BEGIN release-conn: " + toString() + poolObj.toString());
-        }
-
-        if (poolObj.isFree()) {
-            throw new IllegalStateException("Releasing object already freed: " +
-                    db.mConnectionNum);
-        }
-
-        poolObj.release();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.d(TAG, "END release-conn: " + toString() + poolObj.toString());
-        }
-    }
-
-    /**
-     * Returns a list of all database connections in the pool (both free and busy connections).
-     * This method is used when "adb bugreport" is done.
-     */
-    /* package */ synchronized ArrayList<SQLiteDatabase> getConnectionList() {
-        ArrayList<SQLiteDatabase> list = new ArrayList<SQLiteDatabase>();
-        for (int i = mPool.size() - 1; i >= 0; i--) {
-            list.add(mPool.get(i).mDb);
-        }
-        return list;
-    }
-
-    /**
-     * package level access for testing purposes only. otherwise, private should be sufficient.
-     */
-    /* package */ int getFreePoolSize() {
-        int count = 0;
-        for (int i = mPool.size() - 1; i >= 0; i--) {
-            if (mPool.get(i).isFree()) {
-                count++;
-            }
-        }
-        return count++;
-    }
-
-    /**
-     * only for testing purposes
-     */
-    /* package */ ArrayList<PoolObj> getPool() {
-        return mPool;
-    }
-
-    @Override
-    public String toString() {
-        StringBuilder buff = new StringBuilder();
-        buff.append("db: ");
-        buff.append(mParentDbObj.getPath());
-        buff.append(", totalsize = ");
-        buff.append(mPool.size());
-        buff.append(", #free = ");
-        buff.append(getFreePoolSize());
-        buff.append(", maxpoolsize = ");
-        buff.append(mMaxPoolSize);
-        for (PoolObj p : mPool) {
-            buff.append("\n");
-            buff.append(p.toString());
-        }
-        return buff.toString();
-    }
-
-    private void doAsserts() {
-        for (int i = 0; i < mPool.size(); i++) {
-            mPool.get(i).verify();
-            assert mPool.get(i).mDb.mConnectionNum == (i + 1);
-        }
-    }
-
-    /** only used for testing purposes. */
-    /* package */ synchronized void setMaxPoolSize(int size) {
-        mMaxPoolSize = size;
-    }
-
-    /** only used for testing purposes. */
-    /* package */ synchronized int getMaxPoolSize() {
-        return mMaxPoolSize;
-    }
-
-    /** only used for testing purposes. */
-    /* package */ boolean isDatabaseObjFree(SQLiteDatabase db) {
-        return mPool.get(db.mConnectionNum - 1).isFree();
-    }
-
-    /** only used for testing purposes. */
-    /* package */ int getSize() {
-        return mPool.size();
-    }
-
-    /**
-     * represents objects in the connection pool.
-     * package-level access for testing purposes only.
-     */
-    /* package */ static class PoolObj {
-
-        private final SQLiteDatabase mDb;
-        private boolean mFreeBusyFlag = FREE;
-        private static final boolean FREE = true;
-        private static final boolean BUSY = false;
-
-        /** the number of threads holding this connection */
-        // @GuardedBy("this")
-        private int mNumHolders = 0;
-
-        /** contains the threadIds of the threads holding this connection.
-         * used for debugging purposes only.
-         */
-        // @GuardedBy("this")
-        private HashSet<Long> mHolderIds = new HashSet<Long>();
-
-        public PoolObj(SQLiteDatabase db) {
-            mDb = db;
-        }
-
-        private synchronized void acquire() {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                assert isFree();
-                long id = Thread.currentThread().getId();
-                assert !mHolderIds.contains(id);
-                mHolderIds.add(id);
-            }
-
-            mNumHolders++;
-            mFreeBusyFlag = BUSY;
-        }
-
-        private synchronized void release() {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                long id = Thread.currentThread().getId();
-                assert mHolderIds.size() == mNumHolders;
-                assert mHolderIds.contains(id);
-                mHolderIds.remove(id);
-            }
-
-            mNumHolders--;
-            if (mNumHolders == 0) {
-                mFreeBusyFlag = FREE;
-            }
-        }
-
-        private synchronized boolean isFree() {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                verify();
-            }
-            return (mFreeBusyFlag == FREE);
-        }
-
-        private synchronized void verify() {
-            if (mFreeBusyFlag == FREE) {
-                assert mNumHolders == 0;
-            } else {
-                assert mNumHolders > 0;
-            }
-        }
-
-        /**
-         * only for testing purposes
-         */
-        /* package */ synchronized int getNumHolders() {
-            return mNumHolders;
-        }
-
-        @Override
-        public String toString() {
-            StringBuilder buff = new StringBuilder();
-            buff.append(", conn # ");
-            buff.append(mDb.mConnectionNum);
-            buff.append(", mCountHolders = ");
-            synchronized(this) {
-                buff.append(mNumHolders);
-                buff.append(", freeBusyFlag = ");
-                buff.append(mFreeBusyFlag);
-                for (Long l : mHolderIds) {
-                    buff.append(", id = " + l);
-                }
-            }
-            return buff.toString();
-        }
-    }
-}
diff --git a/core/java/android/database/sqlite/SQLiteClosable.java b/core/java/android/database/sqlite/SQLiteClosable.java
index 01e9fb3..7e91a7b 100644
--- a/core/java/android/database/sqlite/SQLiteClosable.java
+++ b/core/java/android/database/sqlite/SQLiteClosable.java
@@ -16,8 +16,6 @@
 
 package android.database.sqlite;
 
-import android.database.CursorWindow;
-
 /**
  * An object created from a SQLiteDatabase that can be closed.
  */
@@ -31,7 +29,7 @@
         synchronized(this) {
             if (mReferenceCount <= 0) {
                 throw new IllegalStateException(
-                        "attempt to re-open an already-closed object: " + getObjInfo());
+                        "attempt to re-open an already-closed object: " + this);
             }
             mReferenceCount++;
         }
@@ -56,22 +54,4 @@
             onAllReferencesReleasedFromContainer();
         }
     }
-
-    private String getObjInfo() {
-        StringBuilder buff = new StringBuilder();
-        buff.append(this.getClass().getName());
-        buff.append(" (");
-        if (this instanceof SQLiteDatabase) {
-            buff.append("database = ");
-            buff.append(((SQLiteDatabase)this).getPath());
-        } else if (this instanceof SQLiteProgram) {
-            buff.append("mSql = ");
-            buff.append(((SQLiteProgram)this).mSql);
-        } else if (this instanceof CursorWindow) {
-            buff.append("mStartPos = ");
-            buff.append(((CursorWindow)this).getStartPosition());
-        }
-        buff.append(") ");
-        return buff.toString();
-    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteCompiledSql.java b/core/java/android/database/sqlite/SQLiteCompiledSql.java
deleted file mode 100644
index dafbc79..0000000
--- a/core/java/android/database/sqlite/SQLiteCompiledSql.java
+++ /dev/null
@@ -1,158 +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 android.database.sqlite;
-
-import android.os.StrictMode;
-import android.util.Log;
-
-/**
- * This class encapsulates compilation of sql statement and release of the compiled statement obj.
- * Once a sql statement is compiled, it is cached in {@link SQLiteDatabase}
- * and it is released in one of the 2 following ways
- * 1. when {@link SQLiteDatabase} object is closed.
- * 2. if this is not cached in {@link SQLiteDatabase}, {@link android.database.Cursor#close()}
- * releaases this obj.
- */
-/* package */ class SQLiteCompiledSql {
-
-    private static final String TAG = "SQLiteCompiledSql";
-
-    /** The database this program is compiled against. */
-    /* package */ final SQLiteDatabase mDatabase;
-
-    /**
-     * Native linkage, do not modify. This comes from the database.
-     */
-    /* package */ final int nHandle;
-
-    /**
-     * Native linkage, do not modify. When non-0 this holds a reference to a valid
-     * sqlite3_statement object. It is only updated by the native code, but may be
-     * checked in this class when the database lock is held to determine if there
-     * is a valid native-side program or not.
-     */
-    /* package */ int nStatement = 0;
-
-    /** the following are for debugging purposes */
-    private String mSqlStmt = null;
-    private final Throwable mStackTrace;
-
-    /** when in cache and is in use, this member is set */
-    private boolean mInUse = false;
-
-    /* package */ SQLiteCompiledSql(SQLiteDatabase db, String sql) {
-        db.verifyDbIsOpen();
-        db.verifyLockOwner();
-        mDatabase = db;
-        mSqlStmt = sql;
-        if (StrictMode.vmSqliteObjectLeaksEnabled()) {
-            mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
-        } else {
-            mStackTrace = null;
-        }
-        nHandle = db.mNativeHandle;
-        native_compile(sql);
-    }
-
-    /* package */ void releaseSqlStatement() {
-        // Note that native_finalize() checks to make sure that nStatement is
-        // non-null before destroying it.
-        if (nStatement != 0) {
-            mDatabase.finalizeStatementLater(nStatement);
-            nStatement = 0;
-        }
-    }
-
-    /**
-     * returns true if acquire() succeeds. false otherwise.
-     */
-    /* package */ synchronized boolean acquire() {
-        if (mInUse) {
-            // it is already in use.
-            return false;
-        }
-        mInUse = true;
-        return true;
-    }
-
-    /* package */ synchronized void release() {
-        mInUse = false;
-    }
-
-    /* package */ synchronized void releaseIfNotInUse() {
-        // if it is not in use, release its memory from the database
-        if (!mInUse) {
-            releaseSqlStatement();
-        }
-    }
-
-    /**
-     * Make sure that the native resource is cleaned up.
-     */
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (nStatement == 0) return;
-            // don't worry about finalizing this object if it is ALREADY in the
-            // queue of statements to be finalized later
-            if (mDatabase.isInQueueOfStatementsToBeFinalized(nStatement)) {
-                return;
-            }
-            // finalizer should NEVER get called
-            // but if the database itself is not closed and is GC'ed, then
-            // all sub-objects attached to the database could end up getting GC'ed too.
-            // in that case, don't print any warning.
-            if (mInUse && mStackTrace != null) {
-                int len = mSqlStmt.length();
-                StrictMode.onSqliteObjectLeaked(
-                    "Releasing statement in a finalizer. Please ensure " +
-                    "that you explicitly call close() on your cursor: " +
-                    mSqlStmt.substring(0, (len > 1000) ? 1000 : len),
-                    mStackTrace);
-            }
-            releaseSqlStatement();
-        } finally {
-            super.finalize();
-        }
-    }
-
-    @Override public String toString() {
-        synchronized(this) {
-            StringBuilder buff = new StringBuilder();
-            buff.append(" nStatement=");
-            buff.append(nStatement);
-            buff.append(", mInUse=");
-            buff.append(mInUse);
-            buff.append(", db=");
-            buff.append(mDatabase.getPath());
-            buff.append(", db_connectionNum=");
-            buff.append(mDatabase.mConnectionNum);
-            buff.append(", sql=");
-            int len = mSqlStmt.length();
-            buff.append(mSqlStmt.substring(0, (len > 100) ? 100 : len));
-            return buff.toString();
-        }
-    }
-
-    /**
-     * Compiles SQL into a SQLite program.
-     *
-     * <P>The database lock must be held when calling this method.
-     * @param sql The SQL to compile.
-     */
-    private final native void native_compile(String sql);
-}
diff --git a/core/java/android/database/sqlite/SQLiteConnection.java b/core/java/android/database/sqlite/SQLiteConnection.java
new file mode 100644
index 0000000..e45d66d
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteConnection.java
@@ -0,0 +1,1149 @@
+/*
+ * 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 android.database.sqlite;
+
+import dalvik.system.BlockGuard;
+import dalvik.system.CloseGuard;
+
+import android.database.Cursor;
+import android.database.CursorWindow;
+import android.database.DatabaseUtils;
+import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.ParcelFileDescriptor;
+import android.util.Log;
+import android.util.LruCache;
+import android.util.Printer;
+
+import java.sql.Date;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.regex.Pattern;
+
+/**
+ * Represents a SQLite database connection.
+ * Each connection wraps an instance of a native <code>sqlite3</code> object.
+ * <p>
+ * When database connection pooling is enabled, there can be multiple active
+ * connections to the same database.  Otherwise there is typically only one
+ * connection per database.
+ * </p><p>
+ * When the SQLite WAL feature is enabled, multiple readers and one writer
+ * can concurrently access the database.  Without WAL, readers and writers
+ * are mutually exclusive.
+ * </p>
+ *
+ * <h2>Ownership and concurrency guarantees</h2>
+ * <p>
+ * Connection objects are not thread-safe.  They are acquired as needed to
+ * perform a database operation and are then returned to the pool.  At any
+ * given time, a connection is either owned and used by a {@link SQLiteSession}
+ * object or the {@link SQLiteConnectionPool}.  Those classes are
+ * responsible for serializing operations to guard against concurrent
+ * use of a connection.
+ * </p><p>
+ * The guarantee of having a single owner allows this class to be implemented
+ * without locks and greatly simplifies resource management.
+ * </p>
+ *
+ * <h2>Encapsulation guarantees</h2>
+ * <p>
+ * The connection object object owns *all* of the SQLite related native
+ * objects that are associated with the connection.  What's more, there are
+ * no other objects in the system that are capable of obtaining handles to
+ * those native objects.  Consequently, when the connection is closed, we do
+ * not have to worry about what other components might have references to
+ * its associated SQLite state -- there are none.
+ * </p><p>
+ * Encapsulation is what ensures that the connection object's
+ * lifecycle does not become a tortured mess of finalizers and reference
+ * queues.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteConnection {
+    private static final String TAG = "SQLiteConnection";
+
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
+    private static final byte[] EMPTY_BYTE_ARRAY = new byte[0];
+
+    private static final Pattern TRIM_SQL_PATTERN = Pattern.compile("[\\s]*\\n+[\\s]*");
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final SQLiteConnectionPool mPool;
+    private final SQLiteDatabaseConfiguration mConfiguration;
+    private final int mConnectionId;
+    private final boolean mIsPrimaryConnection;
+    private final PreparedStatementCache mPreparedStatementCache;
+    private PreparedStatement mPreparedStatementPool;
+
+    // The recent operations log.
+    private final OperationLog mRecentOperations = new OperationLog();
+
+    // The native SQLiteConnection pointer.  (FOR INTERNAL USE ONLY)
+    private int mConnectionPtr;
+
+    private boolean mOnlyAllowReadOnlyOperations;
+
+    private static native int nativeOpen(String path, int openFlags, String label,
+            boolean enableTrace, boolean enableProfile);
+    private static native void nativeClose(int connectionPtr);
+    private static native void nativeRegisterCustomFunction(int connectionPtr,
+            SQLiteCustomFunction function);
+    private static native void nativeSetLocale(int connectionPtr, String locale);
+    private static native int nativePrepareStatement(int connectionPtr, String sql);
+    private static native void nativeFinalizeStatement(int connectionPtr, int statementPtr);
+    private static native int nativeGetParameterCount(int connectionPtr, int statementPtr);
+    private static native boolean nativeIsReadOnly(int connectionPtr, int statementPtr);
+    private static native int nativeGetColumnCount(int connectionPtr, int statementPtr);
+    private static native String nativeGetColumnName(int connectionPtr, int statementPtr,
+            int index);
+    private static native void nativeBindNull(int connectionPtr, int statementPtr,
+            int index);
+    private static native void nativeBindLong(int connectionPtr, int statementPtr,
+            int index, long value);
+    private static native void nativeBindDouble(int connectionPtr, int statementPtr,
+            int index, double value);
+    private static native void nativeBindString(int connectionPtr, int statementPtr,
+            int index, String value);
+    private static native void nativeBindBlob(int connectionPtr, int statementPtr,
+            int index, byte[] value);
+    private static native void nativeResetStatementAndClearBindings(
+            int connectionPtr, int statementPtr);
+    private static native void nativeExecute(int connectionPtr, int statementPtr);
+    private static native long nativeExecuteForLong(int connectionPtr, int statementPtr);
+    private static native String nativeExecuteForString(int connectionPtr, int statementPtr);
+    private static native int nativeExecuteForBlobFileDescriptor(
+            int connectionPtr, int statementPtr);
+    private static native int nativeExecuteForChangedRowCount(int connectionPtr, int statementPtr);
+    private static native long nativeExecuteForLastInsertedRowId(
+            int connectionPtr, int statementPtr);
+    private static native long nativeExecuteForCursorWindow(
+            int connectionPtr, int statementPtr, int windowPtr,
+            int startPos, int requiredPos, boolean countAllRows);
+    private static native int nativeGetDbLookaside(int connectionPtr);
+
+    private SQLiteConnection(SQLiteConnectionPool pool,
+            SQLiteDatabaseConfiguration configuration,
+            int connectionId, boolean primaryConnection) {
+        mPool = pool;
+        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+        mConnectionId = connectionId;
+        mIsPrimaryConnection = primaryConnection;
+        mPreparedStatementCache = new PreparedStatementCache(
+                mConfiguration.maxSqlCacheSize);
+        mCloseGuard.open("close");
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            if (mPool != null && mConnectionPtr != 0) {
+                mPool.onConnectionLeaked();
+            }
+
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    static SQLiteConnection open(SQLiteConnectionPool pool,
+            SQLiteDatabaseConfiguration configuration,
+            int connectionId, boolean primaryConnection) {
+        SQLiteConnection connection = new SQLiteConnection(pool, configuration,
+                connectionId, primaryConnection);
+        try {
+            connection.open();
+            return connection;
+        } catch (SQLiteException ex) {
+            connection.dispose(false);
+            throw ex;
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // Closes the database closes and releases all of its associated resources.
+    // Do not call methods on the connection after it is closed.  It will probably crash.
+    void close() {
+        dispose(false);
+    }
+
+    private void open() {
+        SQLiteGlobal.initializeOnce();
+
+        mConnectionPtr = nativeOpen(mConfiguration.path, mConfiguration.openFlags,
+                mConfiguration.label,
+                SQLiteDebug.DEBUG_SQL_STATEMENTS, SQLiteDebug.DEBUG_SQL_TIME);
+
+        setLocaleFromConfiguration();
+    }
+
+    private void dispose(boolean finalized) {
+        if (mCloseGuard != null) {
+            if (finalized) {
+                mCloseGuard.warnIfOpen();
+            }
+            mCloseGuard.close();
+        }
+
+        if (mConnectionPtr != 0) {
+            mRecentOperations.beginOperation("close", null, null);
+            try {
+                mPreparedStatementCache.evictAll();
+                nativeClose(mConnectionPtr);
+                mConnectionPtr = 0;
+            } finally {
+                mRecentOperations.endOperation();
+            }
+        }
+    }
+
+    private void setLocaleFromConfiguration() {
+        nativeSetLocale(mConnectionPtr, mConfiguration.locale.toString());
+    }
+
+    // Called by SQLiteConnectionPool only.
+    void reconfigure(SQLiteDatabaseConfiguration configuration) {
+        // Register custom functions.
+        final int functionCount = configuration.customFunctions.size();
+        for (int i = 0; i < functionCount; i++) {
+            SQLiteCustomFunction function = configuration.customFunctions.get(i);
+            if (!mConfiguration.customFunctions.contains(function)) {
+                nativeRegisterCustomFunction(mConnectionPtr, function);
+            }
+        }
+
+        // Remember whether locale has changed.
+        boolean localeChanged = !configuration.locale.equals(mConfiguration.locale);
+
+        // Update configuration parameters.
+        mConfiguration.updateParametersFrom(configuration);
+
+        // Update prepared statement cache size.
+        mPreparedStatementCache.resize(configuration.maxSqlCacheSize);
+
+        // Update locale.
+        if (localeChanged) {
+            setLocaleFromConfiguration();
+        }
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // When set to true, executing write operations will throw SQLiteException.
+    // Preparing statements that might write is ok, just don't execute them.
+    void setOnlyAllowReadOnlyOperations(boolean readOnly) {
+        mOnlyAllowReadOnlyOperations = readOnly;
+    }
+
+    // Called by SQLiteConnectionPool only.
+    // Returns true if the prepared statement cache contains the specified SQL.
+    boolean isPreparedStatementInCache(String sql) {
+        return mPreparedStatementCache.get(sql) != null;
+    }
+
+    /**
+     * Gets the unique id of this connection.
+     * @return The connection id.
+     */
+    public int getConnectionId() {
+        return mConnectionId;
+    }
+
+    /**
+     * Returns true if this is the primary database connection.
+     * @return True if this is the primary database connection.
+     */
+    public boolean isPrimaryConnection() {
+        return mIsPrimaryConnection;
+    }
+
+    /**
+     * Prepares a statement for execution but does not bind its parameters or execute it.
+     * <p>
+     * This method can be used to check for syntax errors during compilation
+     * prior to execution of the statement.  If the {@code outStatementInfo} argument
+     * is not null, the provided {@link SQLiteStatementInfo} object is populated
+     * with information about the statement.
+     * </p><p>
+     * A prepared statement makes no reference to the arguments that may eventually
+     * be bound to it, consequently it it possible to cache certain prepared statements
+     * such as SELECT or INSERT/UPDATE statements.  If the statement is cacheable,
+     * then it will be stored in the cache for later.
+     * </p><p>
+     * To take advantage of this behavior as an optimization, the connection pool
+     * provides a method to acquire a connection that already has a given SQL statement
+     * in its prepared statement cache so that it is ready for execution.
+     * </p>
+     *
+     * @param sql The SQL statement to prepare.
+     * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
+     * with information about the statement, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error.
+     */
+    public void prepare(String sql, SQLiteStatementInfo outStatementInfo) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("prepare", sql, null);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                if (outStatementInfo != null) {
+                    outStatementInfo.numParameters = statement.mNumParameters;
+                    outStatementInfo.readOnly = statement.mReadOnly;
+
+                    final int columnCount = nativeGetColumnCount(
+                            mConnectionPtr, statement.mStatementPtr);
+                    if (columnCount == 0) {
+                        outStatementInfo.columnNames = EMPTY_STRING_ARRAY;
+                    } else {
+                        outStatementInfo.columnNames = new String[columnCount];
+                        for (int i = 0; i < columnCount; i++) {
+                            outStatementInfo.columnNames[i] = nativeGetColumnName(
+                                    mConnectionPtr, statement.mStatementPtr, i);
+                        }
+                    }
+                }
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that does not return a result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public void execute(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("execute", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                nativeExecute(mConnectionPtr, statement.mStatementPtr);
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single <code>long</code> result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>long</code>, or zero if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public long executeForLong(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("executeForLong", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                return nativeExecuteForLong(mConnectionPtr, statement.mStatementPtr);
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single {@link String} result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>String</code>, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public String executeForString(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("executeForString", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                return nativeExecuteForString(mConnectionPtr, statement.mStatementPtr);
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single BLOB result as a
+     * file descriptor to a shared memory region.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @return The file descriptor for a shared memory region that contains
+     * the value of the first column in the first row of the result set as a BLOB,
+     * or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("executeForBlobFileDescriptor", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                int fd = nativeExecuteForBlobFileDescriptor(
+                        mConnectionPtr, statement.mStatementPtr);
+                return fd >= 0 ? ParcelFileDescriptor.adoptFd(fd) : null;
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that returns a count of the number of rows
+     * that were changed.  Use for UPDATE or DELETE SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @return The number of rows that were changed.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public int executeForChangedRowCount(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("executeForChangedRowCount", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                return nativeExecuteForChangedRowCount(
+                        mConnectionPtr, statement.mStatementPtr);
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement that returns the row id of the last row inserted
+     * by the statement.  Use for INSERT SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @return The row id of the last row that was inserted, or 0 if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public long executeForLastInsertedRowId(String sql, Object[] bindArgs) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        mRecentOperations.beginOperation("executeForLastInsertedRowId", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                return nativeExecuteForLastInsertedRowId(
+                        mConnectionPtr, statement.mStatementPtr);
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            mRecentOperations.endOperation();
+        }
+    }
+
+    /**
+     * Executes a statement and populates the specified {@link CursorWindow}
+     * with a range of results.  Returns the number of rows that were counted
+     * during query execution.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param window The cursor window to clear and fill.
+     * @param startPos The start position for filling the window.
+     * @param requiredPos The position of a row that MUST be in the window.
+     * If it won't fit, then the query should discard part of what it filled
+     * so that it does.  Must be greater than or equal to <code>startPos</code>.
+     * @param countAllRows True to count all rows that the query would return
+     * regagless of whether they fit in the window.
+     * @return The number of rows that were counted during query execution.  Might
+     * not be all rows in the result set unless <code>countAllRows</code> is true.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public int executeForCursorWindow(String sql, Object[] bindArgs,
+            CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+        if (window == null) {
+            throw new IllegalArgumentException("window must not be null.");
+        }
+
+        int actualPos = -1;
+        int countedRows = -1;
+        int filledRows = -1;
+        mRecentOperations.beginOperation("executeForCursorWindow", sql, bindArgs);
+        try {
+            PreparedStatement statement = acquirePreparedStatement(sql);
+            try {
+                throwIfStatementForbidden(statement);
+                bindArguments(statement, bindArgs);
+                applyBlockGuardPolicy(statement);
+                final long result = nativeExecuteForCursorWindow(
+                        mConnectionPtr, statement.mStatementPtr, window.mWindowPtr,
+                        startPos, requiredPos, countAllRows);
+                actualPos = (int)(result >> 32);
+                countedRows = (int)result;
+                filledRows = window.getNumRows();
+                window.setStartPosition(actualPos);
+                return countedRows;
+            } finally {
+                releasePreparedStatement(statement);
+            }
+        } catch (RuntimeException ex) {
+            mRecentOperations.failOperation(ex);
+            throw ex;
+        } finally {
+            if (mRecentOperations.endOperationDeferLog()) {
+                mRecentOperations.logOperation("window='" + window
+                        + "', startPos=" + startPos
+                        + ", actualPos=" + actualPos
+                        + ", filledRows=" + filledRows
+                        + ", countedRows=" + countedRows);
+            }
+        }
+    }
+
+    private PreparedStatement acquirePreparedStatement(String sql) {
+        PreparedStatement statement = mPreparedStatementCache.get(sql);
+        if (statement != null) {
+            return statement;
+        }
+
+        final int statementPtr = nativePrepareStatement(mConnectionPtr, sql);
+        try {
+            final int numParameters = nativeGetParameterCount(mConnectionPtr, statementPtr);
+            final int type = DatabaseUtils.getSqlStatementType(sql);
+            final boolean readOnly = nativeIsReadOnly(mConnectionPtr, statementPtr);
+            statement = obtainPreparedStatement(sql, statementPtr, numParameters, type, readOnly);
+            if (isCacheable(type)) {
+                mPreparedStatementCache.put(sql, statement);
+                statement.mInCache = true;
+            }
+        } catch (RuntimeException ex) {
+            // Finalize the statement if an exception occurred and we did not add
+            // it to the cache.  If it is already in the cache, then leave it there.
+            if (statement == null || !statement.mInCache) {
+                nativeFinalizeStatement(mConnectionPtr, statementPtr);
+            }
+            throw ex;
+        }
+        return statement;
+    }
+
+    private void releasePreparedStatement(PreparedStatement statement) {
+        if (statement.mInCache) {
+            try {
+                nativeResetStatementAndClearBindings(mConnectionPtr, statement.mStatementPtr);
+            } catch (SQLiteException ex) {
+                // The statement could not be reset due to an error.
+                // The entryRemoved() callback for the cache will recursively call
+                // releasePreparedStatement() again, but this time mInCache will be false
+                // so the statement will be finalized and recycled.
+                if (SQLiteDebug.DEBUG_SQL_CACHE) {
+                    Log.v(TAG, "Could not reset prepared statement due to an exception.  "
+                            + "Removing it from the cache.  SQL: "
+                            + trimSqlForDisplay(statement.mSql), ex);
+                }
+                mPreparedStatementCache.remove(statement.mSql);
+            }
+        } else {
+            nativeFinalizeStatement(mConnectionPtr, statement.mStatementPtr);
+            recyclePreparedStatement(statement);
+        }
+    }
+
+    private void bindArguments(PreparedStatement statement, Object[] bindArgs) {
+        final int count = bindArgs != null ? bindArgs.length : 0;
+        if (count != statement.mNumParameters) {
+            throw new SQLiteBindOrColumnIndexOutOfRangeException(
+                    "Expected " + statement.mNumParameters + " bind arguments but "
+                    + bindArgs.length + " were provided.");
+        }
+        if (count == 0) {
+            return;
+        }
+
+        final int statementPtr = statement.mStatementPtr;
+        for (int i = 0; i < count; i++) {
+            final Object arg = bindArgs[i];
+            switch (DatabaseUtils.getTypeOfObject(arg)) {
+                case Cursor.FIELD_TYPE_NULL:
+                    nativeBindNull(mConnectionPtr, statementPtr, i + 1);
+                    break;
+                case Cursor.FIELD_TYPE_INTEGER:
+                    nativeBindLong(mConnectionPtr, statementPtr, i + 1,
+                            ((Number)arg).longValue());
+                    break;
+                case Cursor.FIELD_TYPE_FLOAT:
+                    nativeBindDouble(mConnectionPtr, statementPtr, i + 1,
+                            ((Number)arg).doubleValue());
+                    break;
+                case Cursor.FIELD_TYPE_BLOB:
+                    nativeBindBlob(mConnectionPtr, statementPtr, i + 1, (byte[])arg);
+                    break;
+                case Cursor.FIELD_TYPE_STRING:
+                default:
+                    if (arg instanceof Boolean) {
+                        // Provide compatibility with legacy applications which may pass
+                        // Boolean values in bind args.
+                        nativeBindLong(mConnectionPtr, statementPtr, i + 1,
+                                ((Boolean)arg).booleanValue() ? 1 : 0);
+                    } else {
+                        nativeBindString(mConnectionPtr, statementPtr, i + 1, arg.toString());
+                    }
+                    break;
+            }
+        }
+    }
+
+    private void throwIfStatementForbidden(PreparedStatement statement) {
+        if (mOnlyAllowReadOnlyOperations && !statement.mReadOnly) {
+            throw new SQLiteException("Cannot execute this statement because it "
+                    + "might modify the database but the connection is read-only.");
+        }
+    }
+
+    private static boolean isCacheable(int statementType) {
+        if (statementType == DatabaseUtils.STATEMENT_UPDATE
+                || statementType == DatabaseUtils.STATEMENT_SELECT) {
+            return true;
+        }
+        return false;
+    }
+
+    private void applyBlockGuardPolicy(PreparedStatement statement) {
+        if (!mConfiguration.isInMemoryDb()) {
+            if (statement.mReadOnly) {
+                BlockGuard.getThreadPolicy().onReadFromDisk();
+            } else {
+                BlockGuard.getThreadPolicy().onWriteToDisk();
+            }
+        }
+    }
+
+    /**
+     * Dumps debugging information about this connection.
+     *
+     * @param printer The printer to receive the dump, not null.
+     */
+    public void dump(Printer printer) {
+        dumpUnsafe(printer);
+    }
+
+    /**
+     * Dumps debugging information about this connection, in the case where the
+     * caller might not actually own the connection.
+     *
+     * This function is written so that it may be called by a thread that does not
+     * own the connection.  We need to be very careful because the connection state is
+     * not synchronized.
+     *
+     * At worst, the method may return stale or slightly wrong data, however
+     * it should not crash.  This is ok as it is only used for diagnostic purposes.
+     *
+     * @param printer The printer to receive the dump, not null.
+     */
+    void dumpUnsafe(Printer printer) {
+        printer.println("Connection #" + mConnectionId + ":");
+        printer.println("  isPrimaryConnection: " + mIsPrimaryConnection);
+        printer.println("  connectionPtr: 0x" + Integer.toHexString(mConnectionPtr));
+        printer.println("  onlyAllowReadOnlyOperations: " + mOnlyAllowReadOnlyOperations);
+
+        mRecentOperations.dump(printer);
+        mPreparedStatementCache.dump(printer);
+    }
+
+    /**
+     * Describes the currently executing operation, in the case where the
+     * caller might not actually own the connection.
+     *
+     * This function is written so that it may be called by a thread that does not
+     * own the connection.  We need to be very careful because the connection state is
+     * not synchronized.
+     *
+     * At worst, the method may return stale or slightly wrong data, however
+     * it should not crash.  This is ok as it is only used for diagnostic purposes.
+     *
+     * @return A description of the current operation including how long it has been running,
+     * or null if none.
+     */
+    String describeCurrentOperationUnsafe() {
+        return mRecentOperations.describeCurrentOperation();
+    }
+
+    /**
+     * Collects statistics about database connection memory usage.
+     *
+     * @param dbStatsList The list to populate.
+     */
+    void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        // Get information about the main database.
+        int lookaside = nativeGetDbLookaside(mConnectionPtr);
+        long pageCount = 0;
+        long pageSize = 0;
+        try {
+            pageCount = executeForLong("PRAGMA page_count;", null);
+            pageSize = executeForLong("PRAGMA page_size;", null);
+        } catch (SQLiteException ex) {
+            // Ignore.
+        }
+        dbStatsList.add(getMainDbStatsUnsafe(lookaside, pageCount, pageSize));
+
+        // Get information about attached databases.
+        // We ignore the first row in the database list because it corresponds to
+        // the main database which we have already described.
+        CursorWindow window = new CursorWindow("collectDbStats");
+        try {
+            executeForCursorWindow("PRAGMA database_list;", null, window, 0, 0, false);
+            for (int i = 1; i < window.getNumRows(); i++) {
+                String name = window.getString(i, 1);
+                String path = window.getString(i, 2);
+                pageCount = 0;
+                pageSize = 0;
+                try {
+                    pageCount = executeForLong("PRAGMA " + name + ".page_count;", null);
+                    pageSize = executeForLong("PRAGMA " + name + ".page_size;", null);
+                } catch (SQLiteException ex) {
+                    // Ignore.
+                }
+                String label = "  (attached) " + name;
+                if (!path.isEmpty()) {
+                    label += ": " + path;
+                }
+                dbStatsList.add(new DbStats(label, pageCount, pageSize, 0, 0, 0, 0));
+            }
+        } catch (SQLiteException ex) {
+            // Ignore.
+        } finally {
+            window.close();
+        }
+    }
+
+    /**
+     * Collects statistics about database connection memory usage, in the case where the
+     * caller might not actually own the connection.
+     *
+     * @return The statistics object, never null.
+     */
+    void collectDbStatsUnsafe(ArrayList<DbStats> dbStatsList) {
+        dbStatsList.add(getMainDbStatsUnsafe(0, 0, 0));
+    }
+
+    private DbStats getMainDbStatsUnsafe(int lookaside, long pageCount, long pageSize) {
+        // The prepared statement cache is thread-safe so we can access its statistics
+        // even if we do not own the database connection.
+        String label = mConfiguration.path;
+        if (!mIsPrimaryConnection) {
+            label += " (" + mConnectionId + ")";
+        }
+        return new DbStats(label, pageCount, pageSize, lookaside,
+                mPreparedStatementCache.hitCount(),
+                mPreparedStatementCache.missCount(),
+                mPreparedStatementCache.size());
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteConnection: " + mConfiguration.path + " (" + mConnectionId + ")";
+    }
+
+    private PreparedStatement obtainPreparedStatement(String sql, int statementPtr,
+            int numParameters, int type, boolean readOnly) {
+        PreparedStatement statement = mPreparedStatementPool;
+        if (statement != null) {
+            mPreparedStatementPool = statement.mPoolNext;
+            statement.mPoolNext = null;
+            statement.mInCache = false;
+        } else {
+            statement = new PreparedStatement();
+        }
+        statement.mSql = sql;
+        statement.mStatementPtr = statementPtr;
+        statement.mNumParameters = numParameters;
+        statement.mType = type;
+        statement.mReadOnly = readOnly;
+        return statement;
+    }
+
+    private void recyclePreparedStatement(PreparedStatement statement) {
+        statement.mSql = null;
+        statement.mPoolNext = mPreparedStatementPool;
+        mPreparedStatementPool = statement;
+    }
+
+    private static String trimSqlForDisplay(String sql) {
+        return TRIM_SQL_PATTERN.matcher(sql).replaceAll(" ");
+    }
+
+    /**
+     * Holder type for a prepared statement.
+     *
+     * Although this object holds a pointer to a native statement object, it
+     * does not have a finalizer.  This is deliberate.  The {@link SQLiteConnection}
+     * owns the statement object and will take care of freeing it when needed.
+     * In particular, closing the connection requires a guarantee of deterministic
+     * resource disposal because all native statement objects must be freed before
+     * the native database object can be closed.  So no finalizers here.
+     */
+    private static final class PreparedStatement {
+        // Next item in pool.
+        public PreparedStatement mPoolNext;
+
+        // The SQL from which the statement was prepared.
+        public String mSql;
+
+        // The native sqlite3_stmt object pointer.
+        // Lifetime is managed explicitly by the connection.
+        public int mStatementPtr;
+
+        // The number of parameters that the prepared statement has.
+        public int mNumParameters;
+
+        // The statement type.
+        public int mType;
+
+        // True if the statement is read-only.
+        public boolean mReadOnly;
+
+        // True if the statement is in the cache.
+        public boolean mInCache;
+    }
+
+    private final class PreparedStatementCache
+            extends LruCache<String, PreparedStatement> {
+        public PreparedStatementCache(int size) {
+            super(size);
+        }
+
+        @Override
+        protected void entryRemoved(boolean evicted, String key,
+                PreparedStatement oldValue, PreparedStatement newValue) {
+            oldValue.mInCache = false;
+            releasePreparedStatement(oldValue);
+        }
+
+        public void dump(Printer printer) {
+            printer.println("  Prepared statement cache:");
+            Map<String, PreparedStatement> cache = snapshot();
+            if (!cache.isEmpty()) {
+                int i = 0;
+                for (Map.Entry<String, PreparedStatement> entry : cache.entrySet()) {
+                    PreparedStatement statement = entry.getValue();
+                    if (statement.mInCache) { // might be false due to a race with entryRemoved
+                        String sql = entry.getKey();
+                        printer.println("    " + i + ": statementPtr=0x"
+                                + Integer.toHexString(statement.mStatementPtr)
+                                + ", numParameters=" + statement.mNumParameters
+                                + ", type=" + statement.mType
+                                + ", readOnly=" + statement.mReadOnly
+                                + ", sql=\"" + trimSqlForDisplay(sql) + "\"");
+                    }
+                    i += 1;
+                }
+            } else {
+                printer.println("    <none>");
+            }
+        }
+    }
+
+    private static final class OperationLog {
+        private static final int MAX_RECENT_OPERATIONS = 10;
+
+        private final Operation[] mOperations = new Operation[MAX_RECENT_OPERATIONS];
+        private int mIndex;
+
+        public void beginOperation(String kind, String sql, Object[] bindArgs) {
+            synchronized (mOperations) {
+                final int index = (mIndex + 1) % MAX_RECENT_OPERATIONS;
+                Operation operation = mOperations[index];
+                if (operation == null) {
+                    operation = new Operation();
+                    mOperations[index] = operation;
+                } else {
+                    operation.mFinished = false;
+                    operation.mException = null;
+                    if (operation.mBindArgs != null) {
+                        operation.mBindArgs.clear();
+                    }
+                }
+                operation.mStartTime = System.currentTimeMillis();
+                operation.mKind = kind;
+                operation.mSql = sql;
+                if (bindArgs != null) {
+                    if (operation.mBindArgs == null) {
+                        operation.mBindArgs = new ArrayList<Object>();
+                    } else {
+                        operation.mBindArgs.clear();
+                    }
+                    for (int i = 0; i < bindArgs.length; i++) {
+                        final Object arg = bindArgs[i];
+                        if (arg != null && arg instanceof byte[]) {
+                            // Don't hold onto the real byte array longer than necessary.
+                            operation.mBindArgs.add(EMPTY_BYTE_ARRAY);
+                        } else {
+                            operation.mBindArgs.add(arg);
+                        }
+                    }
+                }
+                mIndex = index;
+            }
+        }
+
+        public void failOperation(Exception ex) {
+            synchronized (mOperations) {
+                final Operation operation =  mOperations[mIndex];
+                operation.mException = ex;
+            }
+        }
+
+        public boolean endOperationDeferLog() {
+            synchronized (mOperations) {
+                return endOperationDeferLogLocked();
+            }
+        }
+
+        private boolean endOperationDeferLogLocked() {
+            final Operation operation =  mOperations[mIndex];
+            operation.mEndTime = System.currentTimeMillis();
+            operation.mFinished = true;
+            return SQLiteDebug.DEBUG_LOG_SLOW_QUERIES && SQLiteDebug.shouldLogSlowQuery(
+                            operation.mEndTime - operation.mStartTime);
+        }
+
+        public void endOperation() {
+            synchronized (mOperations) {
+                if (endOperationDeferLogLocked()) {
+                    logOperationLocked(null);
+                }
+            }
+        }
+
+        public void logOperation(String detail) {
+            synchronized (mOperations) {
+                logOperationLocked(detail);
+            }
+        }
+
+        private void logOperationLocked(String detail) {
+            final Operation operation =  mOperations[mIndex];
+            StringBuilder msg = new StringBuilder();
+            operation.describe(msg);
+            if (detail != null) {
+                msg.append(", ").append(detail);
+            }
+            Log.d(TAG, msg.toString());
+        }
+
+        public String describeCurrentOperation() {
+            synchronized (mOperations) {
+                final Operation operation = mOperations[mIndex];
+                if (operation != null && !operation.mFinished) {
+                    StringBuilder msg = new StringBuilder();
+                    operation.describe(msg);
+                    return msg.toString();
+                }
+                return null;
+            }
+        }
+
+        public void dump(Printer printer) {
+            synchronized (mOperations) {
+                printer.println("  Most recently executed operations:");
+                int index = mIndex;
+                Operation operation = mOperations[index];
+                if (operation != null) {
+                    int n = 0;
+                    do {
+                        StringBuilder msg = new StringBuilder();
+                        msg.append("    ").append(n).append(": [");
+                        msg.append(operation.getFormattedStartTime());
+                        msg.append("] ");
+                        operation.describe(msg);
+                        printer.println(msg.toString());
+
+                        if (index > 0) {
+                            index -= 1;
+                        } else {
+                            index = MAX_RECENT_OPERATIONS - 1;
+                        }
+                        n += 1;
+                        operation = mOperations[index];
+                    } while (operation != null && n < MAX_RECENT_OPERATIONS);
+                } else {
+                    printer.println("    <none>");
+                }
+            }
+        }
+    }
+
+    private static final class Operation {
+        private static final SimpleDateFormat sDateFormat =
+                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
+
+        public long mStartTime;
+        public long mEndTime;
+        public String mKind;
+        public String mSql;
+        public ArrayList<Object> mBindArgs;
+        public boolean mFinished;
+        public Exception mException;
+
+        public void describe(StringBuilder msg) {
+            msg.append(mKind);
+            if (mFinished) {
+                msg.append(" took ").append(mEndTime - mStartTime).append("ms");
+            } else {
+                msg.append(" started ").append(System.currentTimeMillis() - mStartTime)
+                        .append("ms ago");
+            }
+            msg.append(" - ").append(getStatus());
+            if (mSql != null) {
+                msg.append(", sql=\"").append(trimSqlForDisplay(mSql)).append("\"");
+            }
+            if (mBindArgs != null && mBindArgs.size() != 0) {
+                msg.append(", bindArgs=[");
+                final int count = mBindArgs.size();
+                for (int i = 0; i < count; i++) {
+                    final Object arg = mBindArgs.get(i);
+                    if (i != 0) {
+                        msg.append(", ");
+                    }
+                    if (arg == null) {
+                        msg.append("null");
+                    } else if (arg instanceof byte[]) {
+                        msg.append("<byte[]>");
+                    } else if (arg instanceof String) {
+                        msg.append("\"").append((String)arg).append("\"");
+                    } else {
+                        msg.append(arg);
+                    }
+                }
+                msg.append("]");
+            }
+            if (mException != null) {
+                msg.append(", exception=\"").append(mException.getMessage()).append("\"");
+            }
+        }
+
+        private String getStatus() {
+            if (!mFinished) {
+                return "running";
+            }
+            return mException != null ? "failed" : "succeeded";
+        }
+
+        private String getFormattedStartTime() {
+            return sDateFormat.format(new Date(mStartTime));
+        }
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteConnectionPool.java b/core/java/android/database/sqlite/SQLiteConnectionPool.java
new file mode 100644
index 0000000..b88bfee
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteConnectionPool.java
@@ -0,0 +1,907 @@
+/*
+ * 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 android.database.sqlite;
+
+import dalvik.system.CloseGuard;
+
+import android.database.sqlite.SQLiteDebug.DbStats;
+import android.os.SystemClock;
+import android.util.Log;
+import android.util.PrefixPrinter;
+import android.util.Printer;
+
+import java.io.Closeable;
+import java.util.ArrayList;
+import java.util.Map;
+import java.util.WeakHashMap;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.locks.LockSupport;
+
+/**
+ * Maintains a pool of active SQLite database connections.
+ * <p>
+ * At any given time, a connection is either owned by the pool, or it has been
+ * acquired by a {@link SQLiteSession}.  When the {@link SQLiteSession} is
+ * finished with the connection it is using, it must return the connection
+ * back to the pool.
+ * </p><p>
+ * The pool holds strong references to the connections it owns.  However,
+ * it only holds <em>weak references</em> to the connections that sessions
+ * have acquired from it.  Using weak references in the latter case ensures
+ * that the connection pool can detect when connections have been improperly
+ * abandoned so that it can create new connections to replace them if needed.
+ * </p><p>
+ * The connection pool is thread-safe (but the connections themselves are not).
+ * </p>
+ *
+ * <h2>Exception safety</h2>
+ * <p>
+ * This code attempts to maintain the invariant that opened connections are
+ * always owned.  Unfortunately that means it needs to handle exceptions
+ * all over to ensure that broken connections get cleaned up.  Most
+ * operations invokving SQLite can throw {@link SQLiteException} or other
+ * runtime exceptions.  This is a bit of a pain to deal with because the compiler
+ * cannot help us catch missing exception handling code.
+ * </p><p>
+ * The general rule for this file: If we are making calls out to
+ * {@link SQLiteConnection} then we must be prepared to handle any
+ * runtime exceptions it might throw at us.  Note that out-of-memory
+ * is an {@link Error}, not a {@link RuntimeException}.  We don't trouble ourselves
+ * handling out of memory because it is hard to do anything at all sensible then
+ * and most likely the VM is about to crash.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteConnectionPool implements Closeable {
+    private static final String TAG = "SQLiteConnectionPool";
+
+    // Amount of time to wait in milliseconds before unblocking acquireConnection
+    // and logging a message about the connection pool being busy.
+    private static final long CONNECTION_POOL_BUSY_MILLIS = 30 * 1000; // 30 seconds
+
+    private final CloseGuard mCloseGuard = CloseGuard.get();
+
+    private final Object mLock = new Object();
+    private final AtomicBoolean mConnectionLeaked = new AtomicBoolean();
+    private final SQLiteDatabaseConfiguration mConfiguration;
+    private boolean mIsOpen;
+    private int mNextConnectionId;
+
+    private ConnectionWaiter mConnectionWaiterPool;
+    private ConnectionWaiter mConnectionWaiterQueue;
+
+    // Strong references to all available connections.
+    private final ArrayList<SQLiteConnection> mAvailableNonPrimaryConnections =
+            new ArrayList<SQLiteConnection>();
+    private SQLiteConnection mAvailablePrimaryConnection;
+
+    // Weak references to all acquired connections.  The associated value
+    // is a boolean that indicates whether the connection must be reconfigured
+    // before being returned to the available connection list.
+    // For example, the prepared statement cache size may have changed and
+    // need to be updated.
+    private final WeakHashMap<SQLiteConnection, Boolean> mAcquiredConnections =
+            new WeakHashMap<SQLiteConnection, Boolean>();
+
+    /**
+     * Connection flag: Read-only.
+     * <p>
+     * This flag indicates that the connection will only be used to
+     * perform read-only operations.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_READ_ONLY = 1 << 0;
+
+    /**
+     * Connection flag: Primary connection affinity.
+     * <p>
+     * This flag indicates that the primary connection is required.
+     * This flag helps support legacy applications that expect most data modifying
+     * operations to be serialized by locking the primary database connection.
+     * Setting this flag essentially implements the old "db lock" concept by preventing
+     * an operation from being performed until it can obtain exclusive access to
+     * the primary connection.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY = 1 << 1;
+
+    /**
+     * Connection flag: Connection is being used interactively.
+     * <p>
+     * This flag indicates that the connection is needed by the UI thread.
+     * The connection pool can use this flag to elevate the priority
+     * of the database connection request.
+     * </p>
+     */
+    public static final int CONNECTION_FLAG_INTERACTIVE = 1 << 2;
+
+    private SQLiteConnectionPool(SQLiteDatabaseConfiguration configuration) {
+        mConfiguration = new SQLiteDatabaseConfiguration(configuration);
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
+    }
+
+    /**
+     * Opens a connection pool for the specified database.
+     *
+     * @param configuration The database configuration.
+     * @return The connection pool.
+     *
+     * @throws SQLiteException if a database error occurs.
+     */
+    public static SQLiteConnectionPool open(SQLiteDatabaseConfiguration configuration) {
+        if (configuration == null) {
+            throw new IllegalArgumentException("configuration must not be null.");
+        }
+
+        // Create the pool.
+        SQLiteConnectionPool pool = new SQLiteConnectionPool(configuration);
+        pool.open(); // might throw
+        return pool;
+    }
+
+    // Might throw
+    private void open() {
+        // Open the primary connection.
+        // This might throw if the database is corrupt.
+        mAvailablePrimaryConnection = openConnectionLocked(
+                true /*primaryConnection*/); // might throw
+
+        // Mark the pool as being open for business.
+        mIsOpen = true;
+        mCloseGuard.open("close");
+    }
+
+    /**
+     * Closes the connection pool.
+     * <p>
+     * When the connection pool is closed, it will refuse all further requests
+     * to acquire connections.  All connections that are currently available in
+     * the pool are closed immediately.  Any connections that are still in use
+     * will be closed as soon as they are returned to the pool.
+     * </p>
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     */
+    public void close() {
+        dispose(false);
+    }
+
+    private void dispose(boolean finalized) {
+        if (mCloseGuard != null) {
+            if (finalized) {
+                mCloseGuard.warnIfOpen();
+            }
+            mCloseGuard.close();
+        }
+
+        if (!finalized) {
+            // Close all connections.  We don't need (or want) to do this
+            // when finalized because we don't know what state the connections
+            // themselves will be in.  The finalizer is really just here for CloseGuard.
+            // The connections will take care of themselves when their own finalizers run.
+            synchronized (mLock) {
+                throwIfClosedLocked();
+
+                mIsOpen = false;
+
+                final int count = mAvailableNonPrimaryConnections.size();
+                for (int i = 0; i < count; i++) {
+                    closeConnectionAndLogExceptionsLocked(mAvailableNonPrimaryConnections.get(i));
+                }
+                mAvailableNonPrimaryConnections.clear();
+
+                if (mAvailablePrimaryConnection != null) {
+                    closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+                    mAvailablePrimaryConnection = null;
+                }
+
+                final int pendingCount = mAcquiredConnections.size();
+                if (pendingCount != 0) {
+                    Log.i(TAG, "The connection pool for " + mConfiguration.label
+                            + " has been closed but there are still "
+                            + pendingCount + " connections in use.  They will be closed "
+                            + "as they are released back to the pool.");
+                }
+
+                wakeConnectionWaitersLocked();
+            }
+        }
+    }
+
+    /**
+     * Reconfigures the database configuration of the connection pool and all of its
+     * connections.
+     * <p>
+     * Configuration changes are propagated down to connections immediately if
+     * they are available or as soon as they are released.  This includes changes
+     * that affect the size of the pool.
+     * </p>
+     *
+     * @param configuration The new configuration.
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     */
+    public void reconfigure(SQLiteDatabaseConfiguration configuration) {
+        if (configuration == null) {
+            throw new IllegalArgumentException("configuration must not be null.");
+        }
+
+        synchronized (mLock) {
+            throwIfClosedLocked();
+
+            final boolean poolSizeChanged = mConfiguration.maxConnectionPoolSize
+                    != configuration.maxConnectionPoolSize;
+            mConfiguration.updateParametersFrom(configuration);
+
+            if (poolSizeChanged) {
+                int availableCount = mAvailableNonPrimaryConnections.size();
+                while (availableCount-- > mConfiguration.maxConnectionPoolSize - 1) {
+                    SQLiteConnection connection =
+                            mAvailableNonPrimaryConnections.remove(availableCount);
+                    closeConnectionAndLogExceptionsLocked(connection);
+                }
+            }
+
+            reconfigureAllConnectionsLocked();
+
+            wakeConnectionWaitersLocked();
+        }
+    }
+
+    /**
+     * Acquires a connection from the pool.
+     * <p>
+     * The caller must call {@link #releaseConnection} to release the connection
+     * back to the pool when it is finished.  Failure to do so will result
+     * in much unpleasantness.
+     * </p>
+     *
+     * @param sql If not null, try to find a connection that already has
+     * the specified SQL statement in its prepared statement cache.
+     * @param connectionFlags The connection request flags.
+     * @return The connection that was acquired, never null.
+     *
+     * @throws IllegalStateException if the pool has been closed.
+     * @throws SQLiteException if a database error occurs.
+     */
+    public SQLiteConnection acquireConnection(String sql, int connectionFlags) {
+        return waitForConnection(sql, connectionFlags);
+    }
+
+    /**
+     * Releases a connection back to the pool.
+     * <p>
+     * It is ok to call this method after the pool has closed, to release
+     * connections that were still in use at the time of closure.
+     * </p>
+     *
+     * @param connection The connection to release.  Must not be null.
+     *
+     * @throws IllegalStateException if the connection was not acquired
+     * from this pool or if it has already been released.
+     */
+    public void releaseConnection(SQLiteConnection connection) {
+        synchronized (mLock) {
+            Boolean mustReconfigure = mAcquiredConnections.remove(connection);
+            if (mustReconfigure == null) {
+                throw new IllegalStateException("Cannot perform this operation "
+                        + "because the specified connection was not acquired "
+                        + "from this pool or has already been released.");
+            }
+
+            if (!mIsOpen) {
+                closeConnectionAndLogExceptionsLocked(connection);
+            } else if (connection.isPrimaryConnection()) {
+                assert mAvailablePrimaryConnection == null;
+                try {
+                    if (mustReconfigure == Boolean.TRUE) {
+                        connection.reconfigure(mConfiguration); // might throw
+                    }
+                } catch (RuntimeException ex) {
+                    Log.e(TAG, "Failed to reconfigure released primary connection, closing it: "
+                            + connection, ex);
+                    closeConnectionAndLogExceptionsLocked(connection);
+                    connection = null;
+                }
+                if (connection != null) {
+                    mAvailablePrimaryConnection = connection;
+                }
+                wakeConnectionWaitersLocked();
+            } else if (mAvailableNonPrimaryConnections.size() >=
+                    mConfiguration.maxConnectionPoolSize - 1) {
+                closeConnectionAndLogExceptionsLocked(connection);
+            } else {
+                try {
+                    if (mustReconfigure == Boolean.TRUE) {
+                        connection.reconfigure(mConfiguration); // might throw
+                    }
+                } catch (RuntimeException ex) {
+                    Log.e(TAG, "Failed to reconfigure released non-primary connection, "
+                            + "closing it: " + connection, ex);
+                    closeConnectionAndLogExceptionsLocked(connection);
+                    connection = null;
+                }
+                if (connection != null) {
+                    mAvailableNonPrimaryConnections.add(connection);
+                }
+                wakeConnectionWaitersLocked();
+            }
+        }
+    }
+
+    /**
+     * Returns true if the session should yield the connection due to
+     * contention over available database connections.
+     *
+     * @param connection The connection owned by the session.
+     * @param connectionFlags The connection request flags.
+     * @return True if the session should yield its connection.
+     *
+     * @throws IllegalStateException if the connection was not acquired
+     * from this pool or if it has already been released.
+     */
+    public boolean shouldYieldConnection(SQLiteConnection connection, int connectionFlags) {
+        synchronized (mLock) {
+            if (!mAcquiredConnections.containsKey(connection)) {
+                throw new IllegalStateException("Cannot perform this operation "
+                        + "because the specified connection was not acquired "
+                        + "from this pool or has already been released.");
+            }
+
+            if (!mIsOpen) {
+                return false;
+            }
+
+            return isSessionBlockingImportantConnectionWaitersLocked(
+                    connection.isPrimaryConnection(), connectionFlags);
+        }
+    }
+
+    /**
+     * Collects statistics about database connection memory usage.
+     *
+     * @param dbStatsList The list to populate.
+     */
+    public void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        synchronized (mLock) {
+            if (mAvailablePrimaryConnection != null) {
+                mAvailablePrimaryConnection.collectDbStats(dbStatsList);
+            }
+
+            for (SQLiteConnection connection : mAvailableNonPrimaryConnections) {
+                connection.collectDbStats(dbStatsList);
+            }
+
+            for (SQLiteConnection connection : mAcquiredConnections.keySet()) {
+                connection.collectDbStatsUnsafe(dbStatsList);
+            }
+        }
+    }
+
+    // Might throw.
+    private SQLiteConnection openConnectionLocked(boolean primaryConnection) {
+        final int connectionId = mNextConnectionId++;
+        return SQLiteConnection.open(this, mConfiguration,
+                connectionId, primaryConnection); // might throw
+    }
+
+    void onConnectionLeaked() {
+        // This code is running inside of the SQLiteConnection finalizer.
+        //
+        // We don't know whether it is just the connection that has been finalized (and leaked)
+        // or whether the connection pool has also been or is about to be finalized.
+        // Consequently, it would be a bad idea to try to grab any locks or to
+        // do any significant work here.  So we do the simplest possible thing and
+        // set a flag.  waitForConnection() periodically checks this flag (when it
+        // times out) so that it can recover from leaked connections and wake
+        // itself or other threads up if necessary.
+        //
+        // You might still wonder why we don't try to do more to wake up the waiters
+        // immediately.  First, as explained above, it would be hard to do safely
+        // unless we started an extra Thread to function as a reference queue.  Second,
+        // this is never supposed to happen in normal operation.  Third, there is no
+        // guarantee that the GC will actually detect the leak in a timely manner so
+        // it's not all that important that we recover from the leak in a timely manner
+        // either.  Fourth, if a badly behaved application finds itself hung waiting for
+        // several seconds while waiting for a leaked connection to be detected and recreated,
+        // then perhaps its authors will have added incentive to fix the problem!
+
+        Log.w(TAG, "A SQLiteConnection object for database '"
+                + mConfiguration.label + "' was leaked!  Please fix your application "
+                + "to end transactions in progress properly and to close the database "
+                + "when it is no longer needed.");
+
+        mConnectionLeaked.set(true);
+    }
+
+    // Can't throw.
+    private void closeConnectionAndLogExceptionsLocked(SQLiteConnection connection) {
+        try {
+            connection.close(); // might throw
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "Failed to close connection, its fate is now in the hands "
+                    + "of the merciful GC: " + connection, ex);
+        }
+    }
+
+    // Can't throw.
+    private void reconfigureAllConnectionsLocked() {
+        boolean wake = false;
+        if (mAvailablePrimaryConnection != null) {
+            try {
+                mAvailablePrimaryConnection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure available primary connection, closing it: "
+                        + mAvailablePrimaryConnection, ex);
+                closeConnectionAndLogExceptionsLocked(mAvailablePrimaryConnection);
+                mAvailablePrimaryConnection = null;
+                wake = true;
+            }
+        }
+
+        int count = mAvailableNonPrimaryConnections.size();
+        for (int i = 0; i < count; i++) {
+            final SQLiteConnection connection = mAvailableNonPrimaryConnections.get(i);
+            try {
+                connection.reconfigure(mConfiguration); // might throw
+            } catch (RuntimeException ex) {
+                Log.e(TAG, "Failed to reconfigure available non-primary connection, closing it: "
+                        + connection, ex);
+                closeConnectionAndLogExceptionsLocked(connection);
+                mAvailableNonPrimaryConnections.remove(i--);
+                count -= 1;
+                wake = true;
+            }
+        }
+
+        if (!mAcquiredConnections.isEmpty()) {
+            ArrayList<SQLiteConnection> keysToUpdate = new ArrayList<SQLiteConnection>(
+                    mAcquiredConnections.size());
+            for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
+                if (entry.getValue() != Boolean.TRUE) {
+                    keysToUpdate.add(entry.getKey());
+                }
+            }
+            final int updateCount = keysToUpdate.size();
+            for (int i = 0; i < updateCount; i++) {
+                mAcquiredConnections.put(keysToUpdate.get(i), Boolean.TRUE);
+            }
+        }
+
+        if (wake) {
+            wakeConnectionWaitersLocked();
+        }
+    }
+
+    // Might throw.
+    private SQLiteConnection waitForConnection(String sql, int connectionFlags) {
+        final boolean wantPrimaryConnection =
+                (connectionFlags & CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY) != 0;
+
+        final ConnectionWaiter waiter;
+        synchronized (mLock) {
+            throwIfClosedLocked();
+
+            // Try to acquire a connection.
+            SQLiteConnection connection = null;
+            if (!wantPrimaryConnection) {
+                connection = tryAcquireNonPrimaryConnectionLocked(
+                        sql, connectionFlags); // might throw
+            }
+            if (connection == null) {
+                connection = tryAcquirePrimaryConnectionLocked(connectionFlags); // might throw
+            }
+            if (connection != null) {
+                return connection;
+            }
+
+            // No connections available.  Enqueue a waiter in priority order.
+            final int priority = getPriority(connectionFlags);
+            final long startTime = SystemClock.uptimeMillis();
+            waiter = obtainConnectionWaiterLocked(Thread.currentThread(), startTime,
+                    priority, wantPrimaryConnection, sql, connectionFlags);
+            ConnectionWaiter predecessor = null;
+            ConnectionWaiter successor = mConnectionWaiterQueue;
+            while (successor != null) {
+                if (priority > successor.mPriority) {
+                    waiter.mNext = successor;
+                    break;
+                }
+                predecessor = successor;
+                successor = successor.mNext;
+            }
+            if (predecessor != null) {
+                predecessor.mNext = waiter;
+            } else {
+                mConnectionWaiterQueue = waiter;
+            }
+        }
+
+        // Park the thread until a connection is assigned or the pool is closed.
+        // Rethrow an exception from the wait, if we got one.
+        long busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS;
+        long nextBusyTimeoutTime = waiter.mStartTime + busyTimeoutMillis;
+        for (;;) {
+            // Detect and recover from connection leaks.
+            if (mConnectionLeaked.compareAndSet(true, false)) {
+                wakeConnectionWaitersLocked();
+            }
+
+            // Wait to be unparked (may already have happened), a timeout, or interruption.
+            LockSupport.parkNanos(this, busyTimeoutMillis * 1000000L);
+
+            // Clear the interrupted flag, just in case.
+            Thread.interrupted();
+
+            // Check whether we are done waiting yet.
+            synchronized (mLock) {
+                throwIfClosedLocked();
+
+                SQLiteConnection connection = waiter.mAssignedConnection;
+                if (connection != null) {
+                    recycleConnectionWaiterLocked(waiter);
+                    return connection;
+                }
+
+                RuntimeException ex = waiter.mException;
+                if (ex != null) {
+                    recycleConnectionWaiterLocked(waiter);
+                    throw ex; // rethrow!
+                }
+
+                final long now = SystemClock.uptimeMillis();
+                if (now < nextBusyTimeoutTime) {
+                    busyTimeoutMillis = now - nextBusyTimeoutTime;
+                } else {
+                    logConnectionPoolBusyLocked(now - waiter.mStartTime, connectionFlags);
+                    busyTimeoutMillis = CONNECTION_POOL_BUSY_MILLIS;
+                    nextBusyTimeoutTime = now + busyTimeoutMillis;
+                }
+            }
+        }
+    }
+
+    // Can't throw.
+    private void logConnectionPoolBusyLocked(long waitMillis, int connectionFlags) {
+        final Thread thread = Thread.currentThread();
+        StringBuilder msg = new StringBuilder();
+        msg.append("The connection pool for database '").append(mConfiguration.label);
+        msg.append("' has been unable to grant a connection to thread ");
+        msg.append(thread.getId()).append(" (").append(thread.getName()).append(") ");
+        msg.append("with flags 0x").append(Integer.toHexString(connectionFlags));
+        msg.append(" for ").append(waitMillis * 0.001f).append(" seconds.\n");
+
+        ArrayList<String> requests = new ArrayList<String>();
+        int activeConnections = 0;
+        int idleConnections = 0;
+        if (!mAcquiredConnections.isEmpty()) {
+            for (Map.Entry<SQLiteConnection, Boolean> entry : mAcquiredConnections.entrySet()) {
+                final SQLiteConnection connection = entry.getKey();
+                String description = connection.describeCurrentOperationUnsafe();
+                if (description != null) {
+                    requests.add(description);
+                    activeConnections += 1;
+                } else {
+                    idleConnections += 1;
+                }
+            }
+        }
+        int availableConnections = mAvailableNonPrimaryConnections.size();
+        if (mAvailablePrimaryConnection != null) {
+            availableConnections += 1;
+        }
+
+        msg.append("Connections: ").append(activeConnections).append(" active, ");
+        msg.append(idleConnections).append(" idle, ");
+        msg.append(availableConnections).append(" available.\n");
+
+        if (!requests.isEmpty()) {
+            msg.append("\nRequests in progress:\n");
+            for (String request : requests) {
+                msg.append("  ").append(request).append("\n");
+            }
+        }
+
+        Log.w(TAG, msg.toString());
+    }
+
+    // Can't throw.
+    private void wakeConnectionWaitersLocked() {
+        // Unpark all waiters that have requests that we can fulfill.
+        // This method is designed to not throw runtime exceptions, although we might send
+        // a waiter an exception for it to rethrow.
+        ConnectionWaiter predecessor = null;
+        ConnectionWaiter waiter = mConnectionWaiterQueue;
+        boolean primaryConnectionNotAvailable = false;
+        boolean nonPrimaryConnectionNotAvailable = false;
+        while (waiter != null) {
+            boolean unpark = false;
+            if (!mIsOpen) {
+                unpark = true;
+            } else {
+                try {
+                    SQLiteConnection connection = null;
+                    if (!waiter.mWantPrimaryConnection && !nonPrimaryConnectionNotAvailable) {
+                        connection = tryAcquireNonPrimaryConnectionLocked(
+                                waiter.mSql, waiter.mConnectionFlags); // might throw
+                        if (connection == null) {
+                            nonPrimaryConnectionNotAvailable = true;
+                        }
+                    }
+                    if (connection == null && !primaryConnectionNotAvailable) {
+                        connection = tryAcquirePrimaryConnectionLocked(
+                                waiter.mConnectionFlags); // might throw
+                        if (connection == null) {
+                            primaryConnectionNotAvailable = true;
+                        }
+                    }
+                    if (connection != null) {
+                        waiter.mAssignedConnection = connection;
+                        unpark = true;
+                    } else if (nonPrimaryConnectionNotAvailable && primaryConnectionNotAvailable) {
+                        // There are no connections available and the pool is still open.
+                        // We cannot fulfill any more connection requests, so stop here.
+                        break;
+                    }
+                } catch (RuntimeException ex) {
+                    // Let the waiter handle the exception from acquiring a connection.
+                    waiter.mException = ex;
+                    unpark = true;
+                }
+            }
+
+            final ConnectionWaiter successor = waiter.mNext;
+            if (unpark) {
+                if (predecessor != null) {
+                    predecessor.mNext = successor;
+                } else {
+                    mConnectionWaiterQueue = successor;
+                }
+                waiter.mNext = null;
+
+                LockSupport.unpark(waiter.mThread);
+            } else {
+                predecessor = waiter;
+            }
+            waiter = successor;
+        }
+    }
+
+    // Might throw.
+    private SQLiteConnection tryAcquirePrimaryConnectionLocked(int connectionFlags) {
+        // If the primary connection is available, acquire it now.
+        SQLiteConnection connection = mAvailablePrimaryConnection;
+        if (connection != null) {
+            mAvailablePrimaryConnection = null;
+            finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+            return connection;
+        }
+
+        // Make sure that the primary connection actually exists and has just been acquired.
+        for (SQLiteConnection acquiredConnection : mAcquiredConnections.keySet()) {
+            if (acquiredConnection.isPrimaryConnection()) {
+                return null;
+            }
+        }
+
+        // Uhoh.  No primary connection!  Either this is the first time we asked
+        // for it, or maybe it leaked?
+        connection = openConnectionLocked(true /*primaryConnection*/); // might throw
+        finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+        return connection;
+    }
+
+    // Might throw.
+    private SQLiteConnection tryAcquireNonPrimaryConnectionLocked(
+            String sql, int connectionFlags) {
+        // Try to acquire the next connection in the queue.
+        SQLiteConnection connection;
+        final int availableCount = mAvailableNonPrimaryConnections.size();
+        if (availableCount > 1 && sql != null) {
+            // If we have a choice, then prefer a connection that has the
+            // prepared statement in its cache.
+            for (int i = 0; i < availableCount; i++) {
+                connection = mAvailableNonPrimaryConnections.get(i);
+                if (connection.isPreparedStatementInCache(sql)) {
+                    mAvailableNonPrimaryConnections.remove(i);
+                    finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+                    return connection;
+                }
+            }
+        }
+        if (availableCount > 0) {
+            // Otherwise, just grab the next one.
+            connection = mAvailableNonPrimaryConnections.remove(availableCount - 1);
+            finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+            return connection;
+        }
+
+        // Expand the pool if needed.
+        int openConnections = mAcquiredConnections.size();
+        if (mAvailablePrimaryConnection != null) {
+            openConnections += 1;
+        }
+        if (openConnections >= mConfiguration.maxConnectionPoolSize) {
+            return null;
+        }
+        connection = openConnectionLocked(false /*primaryConnection*/); // might throw
+        finishAcquireConnectionLocked(connection, connectionFlags); // might throw
+        return connection;
+    }
+
+    // Might throw.
+    private void finishAcquireConnectionLocked(SQLiteConnection connection, int connectionFlags) {
+        try {
+            final boolean readOnly = (connectionFlags & CONNECTION_FLAG_READ_ONLY) != 0;
+            connection.setOnlyAllowReadOnlyOperations(readOnly);
+
+            mAcquiredConnections.put(connection, Boolean.FALSE);
+        } catch (RuntimeException ex) {
+            Log.e(TAG, "Failed to prepare acquired connection for session, closing it: "
+                    + connection +", connectionFlags=" + connectionFlags);
+            closeConnectionAndLogExceptionsLocked(connection);
+            throw ex; // rethrow!
+        }
+    }
+
+    private boolean isSessionBlockingImportantConnectionWaitersLocked(
+            boolean holdingPrimaryConnection, int connectionFlags) {
+        ConnectionWaiter waiter = mConnectionWaiterQueue;
+        if (waiter != null) {
+            final int priority = getPriority(connectionFlags);
+            do {
+                // Only worry about blocked connections that have same or lower priority.
+                if (priority > waiter.mPriority) {
+                    break;
+                }
+
+                // If we are holding the primary connection then we are blocking the waiter.
+                // Likewise, if we are holding a non-primary connection and the waiter
+                // would accept a non-primary connection, then we are blocking the waier.
+                if (holdingPrimaryConnection || !waiter.mWantPrimaryConnection) {
+                    return true;
+                }
+
+                waiter = waiter.mNext;
+            } while (waiter != null);
+        }
+        return false;
+    }
+
+    private static int getPriority(int connectionFlags) {
+        return (connectionFlags & CONNECTION_FLAG_INTERACTIVE) != 0 ? 1 : 0;
+    }
+
+    private void throwIfClosedLocked() {
+        if (!mIsOpen) {
+            throw new IllegalStateException("Cannot perform this operation "
+                    + "because the connection pool have been closed.");
+        }
+    }
+
+    private ConnectionWaiter obtainConnectionWaiterLocked(Thread thread, long startTime,
+            int priority, boolean wantPrimaryConnection, String sql, int connectionFlags) {
+        ConnectionWaiter waiter = mConnectionWaiterPool;
+        if (waiter != null) {
+            mConnectionWaiterPool = waiter.mNext;
+            waiter.mNext = null;
+        } else {
+            waiter = new ConnectionWaiter();
+        }
+        waiter.mThread = thread;
+        waiter.mStartTime = startTime;
+        waiter.mPriority = priority;
+        waiter.mWantPrimaryConnection = wantPrimaryConnection;
+        waiter.mSql = sql;
+        waiter.mConnectionFlags = connectionFlags;
+        return waiter;
+    }
+
+    private void recycleConnectionWaiterLocked(ConnectionWaiter waiter) {
+        waiter.mNext = mConnectionWaiterPool;
+        waiter.mThread = null;
+        waiter.mSql = null;
+        waiter.mAssignedConnection = null;
+        waiter.mException = null;
+        mConnectionWaiterPool = waiter;
+    }
+
+    /**
+     * Dumps debugging information about this connection pool.
+     *
+     * @param printer The printer to receive the dump, not null.
+     */
+    public void dump(Printer printer) {
+        Printer indentedPrinter = PrefixPrinter.create(printer, "    ");
+        synchronized (mLock) {
+            printer.println("Connection pool for " + mConfiguration.path + ":");
+            printer.println("  Open: " + mIsOpen);
+            printer.println("  Max connections: " + mConfiguration.maxConnectionPoolSize);
+
+            printer.println("  Available primary connection:");
+            if (mAvailablePrimaryConnection != null) {
+                mAvailablePrimaryConnection.dump(indentedPrinter);
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Available non-primary connections:");
+            if (!mAvailableNonPrimaryConnections.isEmpty()) {
+                final int count = mAvailableNonPrimaryConnections.size();
+                for (int i = 0; i < count; i++) {
+                    mAvailableNonPrimaryConnections.get(i).dump(indentedPrinter);
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Acquired connections:");
+            if (!mAcquiredConnections.isEmpty()) {
+                for (Map.Entry<SQLiteConnection, Boolean> entry :
+                        mAcquiredConnections.entrySet()) {
+                    final SQLiteConnection connection = entry.getKey();
+                    connection.dumpUnsafe(indentedPrinter);
+                    indentedPrinter.println("  Pending reconfiguration: " + entry.getValue());
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+
+            printer.println("  Connection waiters:");
+            if (mConnectionWaiterQueue != null) {
+                int i = 0;
+                final long now = SystemClock.uptimeMillis();
+                for (ConnectionWaiter waiter = mConnectionWaiterQueue; waiter != null;
+                        waiter = waiter.mNext, i++) {
+                    indentedPrinter.println(i + ": waited for "
+                            + ((now - waiter.mStartTime) * 0.001f)
+                            + " ms - thread=" + waiter.mThread
+                            + ", priority=" + waiter.mPriority
+                            + ", sql='" + waiter.mSql + "'");
+                }
+            } else {
+                indentedPrinter.println("<none>");
+            }
+        }
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteConnectionPool: " + mConfiguration.path;
+    }
+
+    private static final class ConnectionWaiter {
+        public ConnectionWaiter mNext;
+        public Thread mThread;
+        public long mStartTime;
+        public int mPriority;
+        public boolean mWantPrimaryConnection;
+        public String mSql;
+        public int mConnectionFlags;
+        public SQLiteConnection mAssignedConnection;
+        public RuntimeException mException;
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteCursor.java b/core/java/android/database/sqlite/SQLiteCursor.java
index 8dcedf2..9dcb498 100644
--- a/core/java/android/database/sqlite/SQLiteCursor.java
+++ b/core/java/android/database/sqlite/SQLiteCursor.java
@@ -43,7 +43,7 @@
     private final String[] mColumns;
 
     /** The query object for the cursor */
-    private SQLiteQuery mQuery;
+    private final SQLiteQuery mQuery;
 
     /** The compiled query this cursor came from */
     private final SQLiteCursorDriver mDriver;
@@ -96,9 +96,6 @@
         if (query == null) {
             throw new IllegalArgumentException("query object cannot be null");
         }
-        if (query.mDatabase == null) {
-            throw new IllegalArgumentException("query.mDatabase cannot be null");
-        }
         if (StrictMode.vmSqliteObjectLeaksEnabled()) {
             mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
         } else {
@@ -109,38 +106,21 @@
         mColumnNameMap = null;
         mQuery = query;
 
-        query.mDatabase.lock(query.mSql);
-        try {
-            // Setup the list of columns
-            int columnCount = mQuery.columnCountLocked();
-            mColumns = new String[columnCount];
-
-            // Read in all column names
-            for (int i = 0; i < columnCount; i++) {
-                String columnName = mQuery.columnNameLocked(i);
-                mColumns[i] = columnName;
-                if (false) {
-                    Log.v("DatabaseWindow", "mColumns[" + i + "] is "
-                            + mColumns[i]);
-                }
-    
-                // Make note of the row ID column index for quick access to it
-                if ("_id".equals(columnName)) {
-                    mRowIdColumnIndex = i;
-                }
+        mColumns = query.getColumnNames();
+        for (int i = 0; i < mColumns.length; i++) {
+            // Make note of the row ID column index for quick access to it
+            if ("_id".equals(mColumns[i])) {
+                mRowIdColumnIndex = i;
             }
-        } finally {
-            query.mDatabase.unlock();
         }
     }
 
     /**
+     * Get the database that this cursor is associated with.
      * @return the SQLiteDatabase that this cursor is associated with.
      */
     public SQLiteDatabase getDatabase() {
-        synchronized (this) {
-            return mQuery.mDatabase;
-        }
+        return mQuery.getDatabase();
     }
 
     @Override
@@ -167,7 +147,7 @@
 
         if (mCount == NO_COUNT) {
             int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos, 0);
-            mCount = getQuery().fillWindow(mWindow, startPos, requiredPos, true);
+            mCount = mQuery.fillWindow(mWindow, startPos, requiredPos, true);
             mCursorWindowCapacity = mWindow.getNumRows();
             if (Log.isLoggable(TAG, Log.DEBUG)) {
                 Log.d(TAG, "received count(*) from native_fill_window: " + mCount);
@@ -175,14 +155,10 @@
         } else {
             int startPos = DatabaseUtils.cursorPickFillWindowStartPosition(requiredPos,
                     mCursorWindowCapacity);
-            getQuery().fillWindow(mWindow, startPos, requiredPos, false);
+            mQuery.fillWindow(mWindow, startPos, requiredPos, false);
         }
     }
 
-    private synchronized SQLiteQuery getQuery() {
-        return mQuery;
-    }
-
     @Override
     public int getColumnIndex(String columnName) {
         // Create mColumnNameMap on demand
@@ -237,75 +213,28 @@
         if (isClosed()) {
             return false;
         }
-        long timeStart = 0;
-        if (false) {
-            timeStart = System.currentTimeMillis();
-        }
 
         synchronized (this) {
+            if (!mQuery.getDatabase().isOpen()) {
+                return false;
+            }
+
             if (mWindow != null) {
                 mWindow.clear();
             }
             mPos = -1;
-            SQLiteDatabase db = null;
-            try {
-                db = mQuery.mDatabase.getDatabaseHandle(mQuery.mSql);
-            } catch (IllegalStateException e) {
-                // for backwards compatibility, just return false
-                Log.w(TAG, "requery() failed " + e.getMessage(), e);
-                return false;
-            }
-            if (!db.equals(mQuery.mDatabase)) {
-                // since we need to use a different database connection handle,
-                // re-compile the query
-                try {
-                    db.lock(mQuery.mSql);
-                } catch (IllegalStateException e) {
-                    // for backwards compatibility, just return false
-                    Log.w(TAG, "requery() failed " + e.getMessage(), e);
-                    return false;
-                }
-                try {
-                    // close the old mQuery object and open a new one
-                    mQuery.close();
-                    mQuery = new SQLiteQuery(db, mQuery);
-                } catch (IllegalStateException e) {
-                    // for backwards compatibility, just return false
-                    Log.w(TAG, "requery() failed " + e.getMessage(), e);
-                    return false;
-                } finally {
-                    db.unlock();
-                }
-            }
-            // This one will recreate the temp table, and get its count
-            mDriver.cursorRequeried(this);
             mCount = NO_COUNT;
-            try {
-                mQuery.requery();
-            } catch (IllegalStateException e) {
-                // for backwards compatibility, just return false
-                Log.w(TAG, "requery() failed " + e.getMessage(), e);
-                return false;
-            }
+
+            mDriver.cursorRequeried(this);
         }
 
-        if (false) {
-            Log.v("DatabaseWindow", "closing window in requery()");
-            Log.v(TAG, "--- Requery()ed cursor " + this + ": " + mQuery);
-        }
-
-        boolean result = false;
         try {
-            result = super.requery();
+            return super.requery();
         } catch (IllegalStateException e) {
             // for backwards compatibility, just return false
             Log.w(TAG, "requery() failed " + e.getMessage(), e);
+            return false;
         }
-        if (false) {
-            long timeEnd = System.currentTimeMillis();
-            Log.v(TAG, "requery (" + (timeEnd - timeStart) + " ms): " + mDriver.toString());
-        }
-        return result;
     }
 
     @Override
@@ -330,20 +259,17 @@
             // if the cursor hasn't been closed yet, close it first
             if (mWindow != null) {
                 if (mStackTrace != null) {
-                    int len = mQuery.mSql.length();
+                    String sql = mQuery.getSql();
+                    int len = sql.length();
                     StrictMode.onSqliteObjectLeaked(
                         "Finalizing a Cursor that has not been deactivated or closed. " +
-                        "database = " + mQuery.mDatabase.getPath() + ", table = " + mEditTable +
-                        ", query = " + mQuery.mSql.substring(0, (len > 1000) ? 1000 : len),
+                        "database = " + mQuery.getDatabase().getLabel() +
+                        ", table = " + mEditTable +
+                        ", query = " + sql.substring(0, (len > 1000) ? 1000 : len),
                         mStackTrace);
                 }
                 close();
                 SQLiteDebug.notifyActiveCursorFinalized();
-            } else {
-                if (false) {
-                    Log.v(TAG, "Finalizing cursor on database = " + mQuery.mDatabase.getPath() +
-                            ", table = " + mEditTable + ", query = " + mQuery.mSql);
-                }
             }
         } finally {
             super.finalize();
diff --git a/core/java/android/database/sqlite/SQLiteCursorDriver.java b/core/java/android/database/sqlite/SQLiteCursorDriver.java
index b3963f9..ad2cdd2 100644
--- a/core/java/android/database/sqlite/SQLiteCursorDriver.java
+++ b/core/java/android/database/sqlite/SQLiteCursorDriver.java
@@ -39,7 +39,7 @@
     void cursorDeactivated();
 
     /**
-     * Called by a SQLiteCursor when it is requeryed.
+     * Called by a SQLiteCursor when it is requeried.
      */
     void cursorRequeried(Cursor cursor);
 
diff --git a/core/java/android/database/sqlite/SQLiteCustomFunction.java b/core/java/android/database/sqlite/SQLiteCustomFunction.java
new file mode 100644
index 0000000..02f3284
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteCustomFunction.java
@@ -0,0 +1,53 @@
+/*
+ * 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 android.database.sqlite;
+
+/**
+ * Describes a custom SQL function.
+ *
+ * @hide
+ */
+public final class SQLiteCustomFunction {
+    public final String name;
+    public final int numArgs;
+    public final SQLiteDatabase.CustomFunction callback;
+
+    /**
+     * Create custom function.
+     *
+     * @param name The name of the sqlite3 function.
+     * @param numArgs The number of arguments for the function, or -1 to
+     * support any number of arguments.
+     * @param callback The callback to invoke when the function is executed.
+     */
+    public SQLiteCustomFunction(String name, int numArgs,
+            SQLiteDatabase.CustomFunction callback) {
+        if (name == null) {
+            throw new IllegalArgumentException("name must not be null.");
+        }
+
+        this.name = name;
+        this.numArgs = numArgs;
+        this.callback = callback;
+    }
+
+    // Called from native.
+    @SuppressWarnings("unused")
+    private void dispatchCallback(String[] args) {
+        callback.callback(args);
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteDatabase.java b/core/java/android/database/sqlite/SQLiteDatabase.java
index f990be6..377a680 100644
--- a/core/java/android/database/sqlite/SQLiteDatabase.java
+++ b/core/java/android/database/sqlite/SQLiteDatabase.java
@@ -16,7 +16,6 @@
 
 package android.database.sqlite;
 
-import android.app.AppGlobals;
 import android.content.ContentValues;
 import android.content.res.Resources;
 import android.database.Cursor;
@@ -25,61 +24,117 @@
 import android.database.DefaultDatabaseErrorHandler;
 import android.database.SQLException;
 import android.database.sqlite.SQLiteDebug.DbStats;
-import android.os.Debug;
-import android.os.StatFs;
-import android.os.SystemClock;
-import android.os.SystemProperties;
+import android.os.Looper;
 import android.text.TextUtils;
 import android.util.EventLog;
 import android.util.Log;
-import android.util.LruCache;
 import android.util.Pair;
-import dalvik.system.BlockGuard;
+import android.util.Printer;
+
+import dalvik.system.CloseGuard;
+
 import java.io.File;
-import java.lang.ref.WeakReference;
 import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Locale;
 import java.util.Map;
-import java.util.Random;
 import java.util.WeakHashMap;
-import java.util.concurrent.TimeUnit;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Pattern;
 
 /**
  * Exposes methods to manage a SQLite database.
- * <p>SQLiteDatabase has methods to create, delete, execute SQL commands, and
+ *
+ * <p>
+ * SQLiteDatabase has methods to create, delete, execute SQL commands, and
  * perform other common database management tasks.
- * <p>See the Notepad sample application in the SDK for an example of creating
+ * </p><p>
+ * See the Notepad sample application in the SDK for an example of creating
  * and managing a database.
- * <p> Database names must be unique within an application, not across all
- * applications.
+ * </p><p>
+ * Database names must be unique within an application, not across all applications.
+ * </p>
  *
  * <h3>Localized Collation - ORDER BY</h3>
- * <p>In addition to SQLite's default <code>BINARY</code> collator, Android supplies
- * two more, <code>LOCALIZED</code>, which changes with the system's current locale
- * if you wire it up correctly (XXX a link needed!), and <code>UNICODE</code>, which
- * is the Unicode Collation Algorithm and not tailored to the current locale.
+ * <p>
+ * In addition to SQLite's default <code>BINARY</code> collator, Android supplies
+ * two more, <code>LOCALIZED</code>, which changes with the system's current locale,
+ * and <code>UNICODE</code>, which is the Unicode Collation Algorithm and not tailored
+ * to the current locale.
+ * </p>
  */
 public class SQLiteDatabase extends SQLiteClosable {
     private static final String TAG = "SQLiteDatabase";
-    private static final boolean ENABLE_DB_SAMPLE = false; // true to enable stats in event log
-    private static final int EVENT_DB_OPERATION = 52000;
+
     private static final int EVENT_DB_CORRUPT = 75004;
 
+    // Stores reference to all databases opened in the current process.
+    // (The referent Object is not used at this time.)
+    // INVARIANT: Guarded by sActiveDatabases.
+    private static WeakHashMap<SQLiteDatabase, Object> sActiveDatabases =
+            new WeakHashMap<SQLiteDatabase, Object>();
+
+    // Thread-local for database sessions that belong to this database.
+    // Each thread has its own database session.
+    // INVARIANT: Immutable.
+    private final ThreadLocal<SQLiteSession> mThreadSession = new ThreadLocal<SQLiteSession>() {
+        @Override
+        protected SQLiteSession initialValue() {
+            return createSession();
+        }
+    };
+
+    // The optional factory to use when creating new Cursors.  May be null.
+    // INVARIANT: Immutable.
+    private final CursorFactory mCursorFactory;
+
+    // Error handler to be used when SQLite returns corruption errors.
+    // INVARIANT: Immutable.
+    private final DatabaseErrorHandler mErrorHandler;
+
+    // Shared database state lock.
+    // This lock guards all of the shared state of the database, such as its
+    // configuration, whether it is open or closed, and so on.  This lock should
+    // be held for as little time as possible.
+    //
+    // The lock MUST NOT be held while attempting to acquire database connections or
+    // while executing SQL statements on behalf of the client as it can lead to deadlock.
+    //
+    // It is ok to hold the lock while reconfiguring the connection pool or dumping
+    // statistics because those operations are non-reentrant and do not try to acquire
+    // connections that might be held by other threads.
+    //
+    // Basic rule: grab the lock, access or modify global state, release the lock, then
+    // do the required SQL work.
+    private final Object mLock = new Object();
+
+    // Warns if the database is finalized without being closed properly.
+    // INVARIANT: Guarded by mLock.
+    private final CloseGuard mCloseGuardLocked = CloseGuard.get();
+
+    // The database configuration.
+    // INVARIANT: Guarded by mLock.
+    private final SQLiteDatabaseConfiguration mConfigurationLocked;
+
+    // The connection pool for the database, null when closed.
+    // The pool itself is thread-safe, but the reference to it can only be acquired
+    // when the lock is held.
+    // INVARIANT: Guarded by mLock.
+    private SQLiteConnectionPool mConnectionPoolLocked;
+
+    // True if the database has attached databases.
+    // INVARIANT: Guarded by mLock.
+    private boolean mHasAttachedDbsLocked;
+
+    // True if the database is in WAL mode.
+    // INVARIANT: Guarded by mLock.
+    private boolean mIsWALEnabledLocked;
+
     /**
-     * Algorithms used in ON CONFLICT clause
-     * http://www.sqlite.org/lang_conflict.html
-     */
-    /**
-     *  When a constraint violation occurs, an immediate ROLLBACK occurs,
+     * When a constraint violation occurs, an immediate ROLLBACK occurs,
      * thus ending the current transaction, and the command aborts with a
      * return code of SQLITE_CONSTRAINT. If no transaction is active
      * (other than the implied transaction that is created on every command)
-     *  then this algorithm works the same as ABORT.
+     * then this algorithm works the same as ABORT.
      */
     public static final int CONFLICT_ROLLBACK = 1;
 
@@ -118,14 +173,15 @@
      * violation occurs then the IGNORE algorithm is used. When this conflict
      * resolution strategy deletes rows in order to satisfy a constraint,
      * it does not invoke delete triggers on those rows.
-     *  This behavior might change in a future release.
+     * This behavior might change in a future release.
      */
     public static final int CONFLICT_REPLACE = 5;
 
     /**
-     * use the following when no conflict action is specified.
+     * Use the following when no conflict action is specified.
      */
     public static final int CONFLICT_NONE = 0;
+
     private static final String[] CONFLICT_VALUES = new String[]
             {"", " OR ROLLBACK ", " OR ABORT ", " OR FAIL ", " OR IGNORE ", " OR REPLACE "};
 
@@ -146,7 +202,7 @@
     public static final int SQLITE_MAX_LIKE_PATTERN_LENGTH = 50000;
 
     /**
-     * Flag for {@link #openDatabase} to open the database for reading and writing.
+     * Open flag: Flag for {@link #openDatabase} to open the database for reading and writing.
      * If the disk is full, this may fail even before you actually write anything.
      *
      * {@more} Note that the value of this flag is 0, so it is the default.
@@ -154,7 +210,7 @@
     public static final int OPEN_READWRITE = 0x00000000;          // update native code if changing
 
     /**
-     * Flag for {@link #openDatabase} to open the database for reading only.
+     * Open flag: Flag for {@link #openDatabase} to open the database for reading only.
      * This is the only reliable way to open a database if the disk may be full.
      */
     public static final int OPEN_READONLY = 0x00000001;           // update native code if changing
@@ -162,7 +218,8 @@
     private static final int OPEN_READ_MASK = 0x00000001;         // update native code if changing
 
     /**
-     * Flag for {@link #openDatabase} to open the database without support for localized collators.
+     * Open flag: Flag for {@link #openDatabase} to open the database without support for
+     * localized collators.
      *
      * {@more} This causes the collator <code>LOCALIZED</code> not to be created.
      * You must be consistent when using this flag to use the setting the database was
@@ -171,190 +228,62 @@
     public static final int NO_LOCALIZED_COLLATORS = 0x00000010;  // update native code if changing
 
     /**
-     * Flag for {@link #openDatabase} to create the database file if it does not already exist.
+     * Open flag: Flag for {@link #openDatabase} to create the database file if it does not
+     * already exist.
      */
     public static final int CREATE_IF_NECESSARY = 0x10000000;     // update native code if changing
 
     /**
-     * Indicates whether the most-recently started transaction has been marked as successful.
-     */
-    private boolean mInnerTransactionIsSuccessful;
-
-    /**
-     * Valid during the life of a transaction, and indicates whether the entire transaction (the
-     * outer one and all of the inner ones) so far has been successful.
-     */
-    private boolean mTransactionIsSuccessful;
-
-    /**
-     * Valid during the life of a transaction.
-     */
-    private SQLiteTransactionListener mTransactionListener;
-
-    /**
-     * this member is set if {@link #execSQL(String)} is used to begin and end transactions.
-     */
-    private boolean mTransactionUsingExecSql;
-
-    /** Synchronize on this when accessing the database */
-    private final DatabaseReentrantLock mLock = new DatabaseReentrantLock(true);
-
-    private long mLockAcquiredWallTime = 0L;
-    private long mLockAcquiredThreadTime = 0L;
-
-    // limit the frequency of complaints about each database to one within 20 sec
-    // unless run command adb shell setprop log.tag.Database VERBOSE
-    private static final int LOCK_WARNING_WINDOW_IN_MS = 20000;
-    /** If the lock is held this long then a warning will be printed when it is released. */
-    private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS = 300;
-    private static final int LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS = 100;
-    private static final int LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT = 2000;
-
-    private static final int SLEEP_AFTER_YIELD_QUANTUM = 1000;
-
-    // The pattern we remove from database filenames before
-    // potentially logging them.
-    private static final Pattern EMAIL_IN_DB_PATTERN = Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+");
-
-    private long mLastLockMessageTime = 0L;
-
-    // Things related to query logging/sampling for debugging
-    // slow/frequent queries during development.  Always log queries
-    // which take (by default) 500ms+; shorter queries are sampled
-    // accordingly.  Commit statements, which are typically slow, are
-    // logged together with the most recently executed SQL statement,
-    // for disambiguation.  The 500ms value is configurable via a
-    // SystemProperty, but developers actively debugging database I/O
-    // should probably use the regular log tunable,
-    // LOG_SLOW_QUERIES_PROPERTY, defined below.
-    private static int sQueryLogTimeInMillis = 0;  // lazily initialized
-    private static final int QUERY_LOG_SQL_LENGTH = 64;
-    private static final String COMMIT_SQL = "COMMIT;";
-    private static final String BEGIN_SQL = "BEGIN;";
-    private final Random mRandom = new Random();
-    /** the last non-commit/rollback sql statement in a transaction */
-    // guarded by 'this'
-    private String mLastSqlStatement = null;
-
-    synchronized String getLastSqlStatement() {
-        return mLastSqlStatement;
-    }
-
-    synchronized void setLastSqlStatement(String sql) {
-        mLastSqlStatement = sql;
-    }
-
-    /** guarded by {@link #mLock} */
-    private long mTransStartTime;
-
-    // String prefix for slow database query EventLog records that show
-    // lock acquistions of the database.
-    /* package */ static final String GET_LOCK_LOG_PREFIX = "GETLOCK:";
-
-    /** Used by native code, do not rename. make it volatile, so it is thread-safe. */
-    /* package */ volatile int mNativeHandle = 0;
-
-    /**
-     * The size, in bytes, of a block on "/data". This corresponds to the Unix
-     * statfs.f_bsize field. note that this field is lazily initialized.
-     */
-    private static int sBlockSize = 0;
-
-    /** The path for the database file */
-    private final String mPath;
-
-    /** The anonymized path for the database file for logging purposes */
-    private String mPathForLogs = null;  // lazily populated
-
-    /** The flags passed to open/create */
-    private final int mFlags;
-
-    /** The optional factory to use when creating new Cursors */
-    private final CursorFactory mFactory;
-
-    private final WeakHashMap<SQLiteClosable, Object> mPrograms;
-
-    /** Default statement-cache size per database connection ( = instance of this class) */
-    private static final int DEFAULT_SQL_CACHE_SIZE = 25;
-
-    /**
-     * for each instance of this class, a LRU cache is maintained to store
-     * the compiled query statement ids returned by sqlite database.
-     *     key = SQL statement with "?" for bind args
-     *     value = {@link SQLiteCompiledSql}
-     * If an application opens the database and keeps it open during its entire life, then
-     * there will not be an overhead of compilation of SQL statements by sqlite.
+     * Absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}.
      *
-     * why is this cache NOT static? because sqlite attaches compiledsql statements to the
-     * struct created when {@link SQLiteDatabase#openDatabase(String, CursorFactory, int)} is
-     * invoked.
-     *
-     * this cache's max size is settable by calling the method
-     * (@link #setMaxSqlCacheSize(int)}.
-     */
-    // guarded by this
-    private LruCache<String, SQLiteCompiledSql> mCompiledQueries;
-
-    /**
-     * absolute max value that can be set by {@link #setMaxSqlCacheSize(int)}
-     * size of each prepared-statement is between 1K - 6K, depending on the complexity of the
-     * SQL statement & schema.
+     * Each prepared-statement is between 1K - 6K, depending on the complexity of the
+     * SQL statement & schema.  A large SQL cache may use a significant amount of memory.
      */
     public static final int MAX_SQL_CACHE_SIZE = 100;
-    private boolean mCacheFullWarning;
 
-    /** Used to find out where this object was created in case it never got closed. */
-    private final Throwable mStackTrace;
-
-    /** stores the list of statement ids that need to be finalized by sqlite */
-    private final ArrayList<Integer> mClosedStatementIds = new ArrayList<Integer>();
-
-    /** {@link DatabaseErrorHandler} to be used when SQLite returns any of the following errors
-     *    Corruption
-     * */
-    private final DatabaseErrorHandler mErrorHandler;
-
-    /** The Database connection pool {@link DatabaseConnectionPool}.
-     * Visibility is package-private for testing purposes. otherwise, private visibility is enough.
-     */
-    /* package */ volatile DatabaseConnectionPool mConnectionPool = null;
-
-    /** Each database connection handle in the pool is assigned a number 1..N, where N is the
-     * size of the connection pool.
-     * The main connection handle to which the pool is attached is assigned a value of 0.
-     */
-    /* package */ final short mConnectionNum;
-
-    /** on pooled database connections, this member points to the parent ( = main)
-     * database connection handle.
-     * package visibility only for testing purposes
-     */
-    /* package */ SQLiteDatabase mParentConnObj = null;
-
-    private static final String MEMORY_DB_PATH = ":memory:";
-
-    /** set to true if the database has attached databases */
-    private volatile boolean mHasAttachedDbs = false;
-
-    /** stores reference to all databases opened in the current process. */
-    private static ArrayList<WeakReference<SQLiteDatabase>> mActiveDatabases =
-            new ArrayList<WeakReference<SQLiteDatabase>>();
-
-    synchronized void addSQLiteClosable(SQLiteClosable closable) {
-        // mPrograms is per instance of SQLiteDatabase and it doesn't actually touch the database
-        // itself. so, there is no need to lock().
-        mPrograms.put(closable, null);
+    private SQLiteDatabase(String path, int openFlags, CursorFactory cursorFactory,
+            DatabaseErrorHandler errorHandler) {
+        mCursorFactory = cursorFactory;
+        mErrorHandler = errorHandler != null ? errorHandler : new DefaultDatabaseErrorHandler();
+        mConfigurationLocked = new SQLiteDatabaseConfiguration(path, openFlags);
     }
 
-    synchronized void removeSQLiteClosable(SQLiteClosable closable) {
-        mPrograms.remove(closable);
+    @Override
+    protected void finalize() throws Throwable {
+        try {
+            dispose(true);
+        } finally {
+            super.finalize();
+        }
     }
 
     @Override
     protected void onAllReferencesReleased() {
-        if (isOpen()) {
-            // close the database which will close all pending statements to be finalized also
-            close();
+        dispose(false);
+    }
+
+    private void dispose(boolean finalized) {
+        final SQLiteConnectionPool pool;
+        synchronized (mLock) {
+            if (mCloseGuardLocked != null) {
+                if (finalized) {
+                    mCloseGuardLocked.warnIfOpen();
+                }
+                mCloseGuardLocked.close();
+            }
+
+            pool = mConnectionPoolLocked;
+            mConnectionPoolLocked = null;
+        }
+
+        if (!finalized) {
+            synchronized (sActiveDatabases) {
+                sActiveDatabases.remove(this);
+            }
+
+            if (pool != null) {
+                pool.close();
+            }
         }
     }
 
@@ -364,7 +293,9 @@
      *
      * @return the number of bytes actually released
      */
-    static public native int releaseMemory();
+    public static int releaseMemory() {
+        return SQLiteGlobal.releaseMemory();
+    }
 
     /**
      * Control whether or not the SQLiteDatabase is made thread-safe by using locks
@@ -372,159 +303,82 @@
      * DB will only be used by a single thread then you should set this to false.
      * The default is true.
      * @param lockingEnabled set to true to enable locks, false otherwise
+     *
+     * @deprecated This method now does nothing.  Do not use.
      */
+    @Deprecated
     public void setLockingEnabled(boolean lockingEnabled) {
-        mLockingEnabled = lockingEnabled;
     }
 
     /**
-     * If set then the SQLiteDatabase is made thread-safe by using locks
-     * around critical sections
+     * Gets a label to use when describing the database in log messages.
+     * @return The label.
      */
-    private boolean mLockingEnabled = true;
+    String getLabel() {
+        synchronized (mLock) {
+            return mConfigurationLocked.label;
+        }
+    }
 
-    /* package */ void onCorruption() {
-        EventLog.writeEvent(EVENT_DB_CORRUPT, mPath);
+    /**
+     * Sends a corruption message to the database error handler.
+     */
+    void onCorruption() {
+        EventLog.writeEvent(EVENT_DB_CORRUPT, getLabel());
         mErrorHandler.onCorruption(this);
     }
 
     /**
-     * Locks the database for exclusive access. The database lock must be held when
-     * touch the native sqlite3* object since it is single threaded and uses
-     * a polling lock contention algorithm. The lock is recursive, and may be acquired
-     * multiple times by the same thread. This is a no-op if mLockingEnabled is false.
+     * Gets the {@link SQLiteSession} that belongs to this thread for this database.
+     * Once a thread has obtained a session, it will continue to obtain the same
+     * session even after the database has been closed (although the session will not
+     * be usable).  However, a thread that does not already have a session cannot
+     * obtain one after the database has been closed.
      *
-     * @see #unlock()
+     * The idea is that threads that have active connections to the database may still
+     * have work to complete even after the call to {@link #close}.  Active database
+     * connections are not actually disposed until they are released by the threads
+     * that own them.
+     *
+     * @return The session, never null.
+     *
+     * @throws IllegalStateException if the thread does not yet have a session and
+     * the database is not open.
      */
-    /* package */ void lock(String sql) {
-        lock(sql, false);
+    SQLiteSession getThreadSession() {
+        return mThreadSession.get(); // initialValue() throws if database closed
     }
 
-    /* pachage */ void lock() {
-        lock(null, false);
-    }
-
-    private static final long LOCK_WAIT_PERIOD = 30L;
-    private void lock(String sql, boolean forced) {
-        // make sure this method is NOT being called from a 'synchronized' method
-        if (Thread.holdsLock(this)) {
-            Log.w(TAG, "don't lock() while in a synchronized method");
+    SQLiteSession createSession() {
+        final SQLiteConnectionPool pool;
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+            pool = mConnectionPoolLocked;
         }
-        verifyDbIsOpen();
-        if (!forced && !mLockingEnabled) return;
-        boolean done = false;
-        long timeStart = SystemClock.uptimeMillis();
-        while (!done) {
-            try {
-                // wait for 30sec to acquire the lock
-                done = mLock.tryLock(LOCK_WAIT_PERIOD, TimeUnit.SECONDS);
-                if (!done) {
-                    // lock not acquired in NSec. print a message and stacktrace saying the lock
-                    // has not been available for 30sec.
-                    Log.w(TAG, "database lock has not been available for " + LOCK_WAIT_PERIOD +
-                            " sec. Current Owner of the lock is " + mLock.getOwnerDescription() +
-                            ". Continuing to wait in thread: " + Thread.currentThread().getId());
-                }
-            } catch (InterruptedException e) {
-                // ignore the interruption
-            }
-        }
-        if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
-            if (mLock.getHoldCount() == 1) {
-                // Use elapsed real-time since the CPU may sleep when waiting for IO
-                mLockAcquiredWallTime = SystemClock.elapsedRealtime();
-                mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
-            }
-        }
-        if (sql != null) {
-            if (ENABLE_DB_SAMPLE)  {
-                logTimeStat(sql, timeStart, GET_LOCK_LOG_PREFIX);
-            }
-        }
-    }
-    private static class DatabaseReentrantLock extends ReentrantLock {
-        DatabaseReentrantLock(boolean fair) {
-            super(fair);
-        }
-        @Override
-        public Thread getOwner() {
-            return super.getOwner();
-        }
-        public String getOwnerDescription() {
-            Thread t = getOwner();
-            return (t== null) ? "none" : String.valueOf(t.getId());
-        }
+        return new SQLiteSession(pool);
     }
 
     /**
-     * Locks the database for exclusive access. The database lock must be held when
-     * touch the native sqlite3* object since it is single threaded and uses
-     * a polling lock contention algorithm. The lock is recursive, and may be acquired
-     * multiple times by the same thread.
+     * Gets default connection flags that are appropriate for this thread, taking into
+     * account whether the thread is acting on behalf of the UI.
      *
-     * @see #unlockForced()
+     * @param readOnly True if the connection should be read-only.
+     * @return The connection flags.
      */
-    private void lockForced() {
-        lock(null, true);
+    int getThreadDefaultConnectionFlags(boolean readOnly) {
+        int flags = readOnly ? SQLiteConnectionPool.CONNECTION_FLAG_READ_ONLY :
+                SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY;
+        if (isMainThread()) {
+            flags |= SQLiteConnectionPool.CONNECTION_FLAG_INTERACTIVE;
+        }
+        return flags;
     }
 
-    private void lockForced(String sql) {
-        lock(sql, true);
-    }
-
-    /**
-     * Releases the database lock. This is a no-op if mLockingEnabled is false.
-     *
-     * @see #unlock()
-     */
-    /* package */ void unlock() {
-        if (!mLockingEnabled) return;
-        if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
-            if (mLock.getHoldCount() == 1) {
-                checkLockHoldTime();
-            }
-        }
-        mLock.unlock();
-    }
-
-    /**
-     * Releases the database lock.
-     *
-     * @see #unlockForced()
-     */
-    private void unlockForced() {
-        if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING) {
-            if (mLock.getHoldCount() == 1) {
-                checkLockHoldTime();
-            }
-        }
-        mLock.unlock();
-    }
-
-    private void checkLockHoldTime() {
-        // Use elapsed real-time since the CPU may sleep when waiting for IO
-        long elapsedTime = SystemClock.elapsedRealtime();
-        long lockedTime = elapsedTime - mLockAcquiredWallTime;
-        if (lockedTime < LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT &&
-                !Log.isLoggable(TAG, Log.VERBOSE) &&
-                (elapsedTime - mLastLockMessageTime) < LOCK_WARNING_WINDOW_IN_MS) {
-            return;
-        }
-        if (lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS) {
-            int threadTime = (int)
-                    ((Debug.threadCpuTimeNanos() - mLockAcquiredThreadTime) / 1000000);
-            if (threadTime > LOCK_ACQUIRED_WARNING_THREAD_TIME_IN_MS ||
-                    lockedTime > LOCK_ACQUIRED_WARNING_TIME_IN_MS_ALWAYS_PRINT) {
-                mLastLockMessageTime = elapsedTime;
-                String msg = "lock held on " + mPath + " for " + lockedTime + "ms. Thread time was "
-                        + threadTime + "ms";
-                if (SQLiteDebug.DEBUG_LOCK_TIME_TRACKING_STACK_TRACE) {
-                    Log.d(TAG, msg, new Exception());
-                } else {
-                    Log.d(TAG, msg);
-                }
-            }
-        }
+    private static boolean isMainThread() {
+        // FIXME: There should be a better way to do this.
+        // Would also be nice to have something that would work across Binder calls.
+        Looper looper = Looper.myLooper();
+        return looper != null && looper == Looper.getMainLooper();
     }
 
     /**
@@ -636,50 +490,9 @@
 
     private void beginTransaction(SQLiteTransactionListener transactionListener,
             boolean exclusive) {
-        verifyDbIsOpen();
-        lockForced(BEGIN_SQL);
-        boolean ok = false;
-        try {
-            // If this thread already had the lock then get out
-            if (mLock.getHoldCount() > 1) {
-                if (mInnerTransactionIsSuccessful) {
-                    String msg = "Cannot call beginTransaction between "
-                            + "calling setTransactionSuccessful and endTransaction";
-                    IllegalStateException e = new IllegalStateException(msg);
-                    Log.e(TAG, "beginTransaction() failed", e);
-                    throw e;
-                }
-                ok = true;
-                return;
-            }
-
-            // This thread didn't already have the lock, so begin a database
-            // transaction now.
-            if (exclusive && mConnectionPool == null) {
-                execSQL("BEGIN EXCLUSIVE;");
-            } else {
-                execSQL("BEGIN IMMEDIATE;");
-            }
-            mTransStartTime = SystemClock.uptimeMillis();
-            mTransactionListener = transactionListener;
-            mTransactionIsSuccessful = true;
-            mInnerTransactionIsSuccessful = false;
-            if (transactionListener != null) {
-                try {
-                    transactionListener.onBegin();
-                } catch (RuntimeException e) {
-                    execSQL("ROLLBACK;");
-                    throw e;
-                }
-            }
-            ok = true;
-        } finally {
-            if (!ok) {
-                // beginTransaction is called before the try block so we must release the lock in
-                // the case of failure.
-                unlockForced();
-            }
-        }
+        getThreadSession().beginTransaction(exclusive ? SQLiteSession.TRANSACTION_MODE_EXCLUSIVE :
+                SQLiteSession.TRANSACTION_MODE_IMMEDIATE, transactionListener,
+                getThreadDefaultConnectionFlags(false /*readOnly*/));
     }
 
     /**
@@ -687,68 +500,7 @@
      * are committed and rolled back.
      */
     public void endTransaction() {
-        verifyLockOwner();
-        try {
-            if (mInnerTransactionIsSuccessful) {
-                mInnerTransactionIsSuccessful = false;
-            } else {
-                mTransactionIsSuccessful = false;
-            }
-            if (mLock.getHoldCount() != 1) {
-                return;
-            }
-            RuntimeException savedException = null;
-            if (mTransactionListener != null) {
-                try {
-                    if (mTransactionIsSuccessful) {
-                        mTransactionListener.onCommit();
-                    } else {
-                        mTransactionListener.onRollback();
-                    }
-                } catch (RuntimeException e) {
-                    savedException = e;
-                    mTransactionIsSuccessful = false;
-                }
-            }
-            if (mTransactionIsSuccessful) {
-                execSQL(COMMIT_SQL);
-                // if write-ahead logging is used, we have to take care of checkpoint.
-                // TODO: should applications be given the flexibility of choosing when to
-                // trigger checkpoint?
-                // for now, do checkpoint after every COMMIT because that is the fastest
-                // way to guarantee that readers will see latest data.
-                // but this is the slowest way to run sqlite with in write-ahead logging mode.
-                if (this.mConnectionPool != null) {
-                    execSQL("PRAGMA wal_checkpoint;");
-                    if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
-                        Log.i(TAG, "PRAGMA wal_Checkpoint done");
-                    }
-                }
-                // log the transaction time to the Eventlog.
-                if (ENABLE_DB_SAMPLE) {
-                    logTimeStat(getLastSqlStatement(), mTransStartTime, COMMIT_SQL);
-                }
-            } else {
-                try {
-                    execSQL("ROLLBACK;");
-                    if (savedException != null) {
-                        throw savedException;
-                    }
-                } catch (SQLException e) {
-                    if (false) {
-                        Log.d(TAG, "exception during rollback, maybe the DB previously "
-                                + "performed an auto-rollback");
-                    }
-                }
-            }
-        } finally {
-            mTransactionListener = null;
-            unlockForced();
-            if (false) {
-                Log.v(TAG, "unlocked " + Thread.currentThread()
-                        + ", holdCount is " + mLock.getHoldCount());
-            }
-        }
+        getThreadSession().endTransaction();
     }
 
     /**
@@ -761,86 +513,46 @@
      * transaction is already marked as successful.
      */
     public void setTransactionSuccessful() {
-        verifyDbIsOpen();
-        if (!mLock.isHeldByCurrentThread()) {
-            throw new IllegalStateException("no transaction pending");
-        }
-        if (mInnerTransactionIsSuccessful) {
-            throw new IllegalStateException(
-                    "setTransactionSuccessful may only be called once per call to beginTransaction");
-        }
-        mInnerTransactionIsSuccessful = true;
+        getThreadSession().setTransactionSuccessful();
     }
 
     /**
-     * return true if there is a transaction pending
+     * Returns true if the current thread has a transaction pending.
+     *
+     * @return True if the current thread is in a transaction.
      */
     public boolean inTransaction() {
-        return mLock.getHoldCount() > 0 || mTransactionUsingExecSql;
-    }
-
-    /* package */ synchronized void setTransactionUsingExecSqlFlag() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.i(TAG, "found execSQL('begin transaction')");
-        }
-        mTransactionUsingExecSql = true;
-    }
-
-    /* package */ synchronized void resetTransactionUsingExecSqlFlag() {
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            if (mTransactionUsingExecSql) {
-                Log.i(TAG, "found execSQL('commit or end or rollback')");
-            }
-        }
-        mTransactionUsingExecSql = false;
+        return getThreadSession().hasTransaction();
     }
 
     /**
-     * Returns true if the caller is considered part of the current transaction, if any.
+     * Returns true if the current thread is holding an active connection to the database.
      * <p>
-     * Caller is part of the current transaction if either of the following is true
-     * <ol>
-     *   <li>If transaction is started by calling beginTransaction() methods AND if the caller is
-     *   in the same thread as the thread that started the transaction.
-     *   </li>
-     *   <li>If the transaction is started by calling {@link #execSQL(String)} like this:
-     *   execSQL("BEGIN transaction"). In this case, every thread in the process is considered
-     *   part of the current transaction.</li>
-     * </ol>
+     * The name of this method comes from a time when having an active connection
+     * to the database meant that the thread was holding an actual lock on the
+     * database.  Nowadays, there is no longer a true "database lock" although threads
+     * may block if they cannot acquire a database connection to perform a
+     * particular operation.
+     * </p>
      *
-     * @return true if the caller is considered part of the current transaction, if any.
-     */
-    /* package */ synchronized boolean amIInTransaction() {
-        // always do this test on the main database connection - NOT on pooled database connection
-        // since transactions always occur on the main database connections only.
-        SQLiteDatabase db = (isPooledConnection()) ? mParentConnObj : this;
-        boolean b = (!db.inTransaction()) ? false :
-                db.mTransactionUsingExecSql || db.mLock.isHeldByCurrentThread();
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.i(TAG, "amIinTransaction: " + b);
-        }
-        return b;
-    }
-
-    /**
-     * Checks if the database lock is held by this thread.
-     *
-     * @return true, if this thread is holding the database lock.
+     * @return True if the current thread is holding an active connection to the database.
      */
     public boolean isDbLockedByCurrentThread() {
-        return mLock.isHeldByCurrentThread();
+        return getThreadSession().hasConnection();
     }
 
     /**
-     * Checks if the database is locked by another thread. This is
-     * just an estimate, since this status can change at any time,
-     * including after the call is made but before the result has
-     * been acted upon.
+     * Always returns false.
+     * <p>
+     * There is no longer the concept of a database lock, so this method always returns false.
+     * </p>
      *
-     * @return true, if the database is locked by another thread
+     * @return False.
+     * @deprecated Always returns false.  Do not use this method.
      */
+    @Deprecated
     public boolean isDbLockedByOtherThreads() {
-        return !mLock.isHeldByCurrentThread() && mLock.isLocked();
+        return false;
     }
 
     /**
@@ -884,46 +596,12 @@
         return yieldIfContendedHelper(true /* check yielding */, sleepAfterYieldDelay);
     }
 
-    private boolean yieldIfContendedHelper(boolean checkFullyYielded, long sleepAfterYieldDelay) {
-        if (mLock.getQueueLength() == 0) {
-            // Reset the lock acquire time since we know that the thread was willing to yield
-            // the lock at this time.
-            mLockAcquiredWallTime = SystemClock.elapsedRealtime();
-            mLockAcquiredThreadTime = Debug.threadCpuTimeNanos();
-            return false;
-        }
-        setTransactionSuccessful();
-        SQLiteTransactionListener transactionListener = mTransactionListener;
-        endTransaction();
-        if (checkFullyYielded) {
-            if (this.isDbLockedByCurrentThread()) {
-                throw new IllegalStateException(
-                        "Db locked more than once. yielfIfContended cannot yield");
-            }
-        }
-        if (sleepAfterYieldDelay > 0) {
-            // Sleep for up to sleepAfterYieldDelay milliseconds, waking up periodically to
-            // check if anyone is using the database.  If the database is not contended,
-            // retake the lock and return.
-            long remainingDelay = sleepAfterYieldDelay;
-            while (remainingDelay > 0) {
-                try {
-                    Thread.sleep(remainingDelay < SLEEP_AFTER_YIELD_QUANTUM ?
-                            remainingDelay : SLEEP_AFTER_YIELD_QUANTUM);
-                } catch (InterruptedException e) {
-                    Thread.interrupted();
-                }
-                remainingDelay -= SLEEP_AFTER_YIELD_QUANTUM;
-                if (mLock.getQueueLength() == 0) {
-                    break;
-                }
-            }
-        }
-        beginTransactionWithListener(transactionListener);
-        return true;
+    private boolean yieldIfContendedHelper(boolean throwIfUnsafe, long sleepAfterYieldDelay) {
+        return getThreadSession().yieldTransaction(sleepAfterYieldDelay, throwIfUnsafe);
     }
 
     /**
+     * Deprecated.
      * @deprecated This method no longer serves any useful purpose and has been deprecated.
      */
     @Deprecated
@@ -932,19 +610,6 @@
     }
 
     /**
-     * Used to allow returning sub-classes of {@link Cursor} when calling query.
-     */
-    public interface CursorFactory {
-        /**
-         * See
-         * {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
-         */
-        public Cursor newCursor(SQLiteDatabase db,
-                SQLiteCursorDriver masterQuery, String editTable,
-                SQLiteQuery query);
-    }
-
-    /**
      * Open the database according to the flags {@link #OPEN_READWRITE}
      * {@link #OPEN_READONLY} {@link #CREATE_IF_NECESSARY} and/or {@link #NO_LOCALIZED_COLLATORS}.
      *
@@ -983,50 +648,9 @@
      */
     public static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
             DatabaseErrorHandler errorHandler) {
-        SQLiteDatabase sqliteDatabase = openDatabase(path, factory, flags, errorHandler,
-                (short) 0 /* the main connection handle */);
-
-        // set sqlite pagesize to mBlockSize
-        if (sBlockSize == 0) {
-            // TODO: "/data" should be a static final String constant somewhere. it is hardcoded
-            // in several places right now.
-            sBlockSize = new StatFs("/data").getBlockSize();
-        }
-        sqliteDatabase.setPageSize(sBlockSize);
-        sqliteDatabase.setJournalMode(path, "TRUNCATE");
-
-        // add this database to the list of databases opened in this process
-        synchronized(mActiveDatabases) {
-            mActiveDatabases.add(new WeakReference<SQLiteDatabase>(sqliteDatabase));
-        }
-        return sqliteDatabase;
-    }
-
-    private static SQLiteDatabase openDatabase(String path, CursorFactory factory, int flags,
-            DatabaseErrorHandler errorHandler, short connectionNum) {
-        SQLiteDatabase db = new SQLiteDatabase(path, factory, flags, errorHandler, connectionNum);
-        try {
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                Log.i(TAG, "opening the db : " + path);
-            }
-            // Open the database.
-            db.dbopen(path, flags);
-            db.setLocale(Locale.getDefault());
-            if (SQLiteDebug.DEBUG_SQL_STATEMENTS) {
-                db.enableSqlTracing(path, connectionNum);
-            }
-            if (SQLiteDebug.DEBUG_SQL_TIME) {
-                db.enableSqlProfiling(path, connectionNum);
-            }
-            return db;
-        } catch (SQLiteDatabaseCorruptException e) {
-            db.mErrorHandler.onCorruption(db);
-            return SQLiteDatabase.openDatabase(path, factory, flags, errorHandler);
-        } catch (SQLiteException e) {
-            Log.e(TAG, "Failed to open the database. closing it.", e);
-            db.close();
-            throw e;
-        }
+        SQLiteDatabase db = new SQLiteDatabase(path, flags, factory, errorHandler);
+        db.open();
+        return db;
     }
 
     /**
@@ -1051,16 +675,46 @@
         return openDatabase(path, factory, CREATE_IF_NECESSARY, errorHandler);
     }
 
-    private void setJournalMode(final String dbPath, final String mode) {
-        // journal mode can be set only for non-memory databases
+    private void open() {
+        try {
+            try {
+                openInner();
+            } catch (SQLiteDatabaseCorruptException ex) {
+                onCorruption();
+                openInner();
+            }
+
+            // Disable WAL if it was previously enabled.
+            setJournalMode("TRUNCATE");
+        } catch (SQLiteException ex) {
+            Log.e(TAG, "Failed to open database '" + getLabel() + "'.", ex);
+            close();
+            throw ex;
+        }
+    }
+
+    private void openInner() {
+        synchronized (mLock) {
+            assert mConnectionPoolLocked == null;
+            mConnectionPoolLocked = SQLiteConnectionPool.open(mConfigurationLocked);
+            mCloseGuardLocked.open("close");
+        }
+
+        synchronized (sActiveDatabases) {
+            sActiveDatabases.put(this, null);
+        }
+    }
+
+    private void setJournalMode(String mode) {
+        // Journal mode can be set only for non-memory databases
         // AND can't be set for readonly databases
-        if (dbPath.equalsIgnoreCase(MEMORY_DB_PATH) || isReadOnly()) {
+        if (isInMemoryDatabase() || isReadOnly()) {
             return;
         }
         String s = DatabaseUtils.stringForQuery(this, "PRAGMA journal_mode=" + mode, null);
         if (!s.equalsIgnoreCase(mode)) {
-            Log.e(TAG, "setting journal_mode to " + mode + " failed for db: " + dbPath +
-                    " (on pragma set journal_mode, sqlite returned:" + s);
+            Log.e(TAG, "setting journal_mode to " + mode + " failed for db: " + getLabel()
+                    + " (on pragma set journal_mode, sqlite returned:" + s);
         }
     }
 
@@ -1077,159 +731,37 @@
      */
     public static SQLiteDatabase create(CursorFactory factory) {
         // This is a magic string with special meaning for SQLite.
-        return openDatabase(MEMORY_DB_PATH, factory, CREATE_IF_NECESSARY);
+        return openDatabase(SQLiteDatabaseConfiguration.MEMORY_DB_PATH,
+                factory, CREATE_IF_NECESSARY);
     }
 
     /**
      * Close the database.
      */
     public void close() {
-        if (!isOpen()) {
-            return;
-        }
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            Log.i(TAG, "closing db: " + mPath + " (connection # " + mConnectionNum);
-        }
-        lock();
-        try {
-            // some other thread could have closed this database while I was waiting for lock.
-            // check the database state
-            if (!isOpen()) {
-                return;
-            }
-            closeClosable();
-            // finalize ALL statements queued up so far
-            closePendingStatements();
-            releaseCustomFunctions();
-            // close this database instance - regardless of its reference count value
-            closeDatabase();
-            if (mConnectionPool != null) {
-                if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    assert mConnectionPool != null;
-                    Log.i(TAG, mConnectionPool.toString());
-                }
-                mConnectionPool.close();
-            }
-        } finally {
-            unlock();
-        }
-    }
-
-    private void closeClosable() {
-        /* deallocate all compiled SQL statement objects from mCompiledQueries cache.
-         * this should be done before de-referencing all {@link SQLiteClosable} objects
-         * from this database object because calling
-         * {@link SQLiteClosable#onAllReferencesReleasedFromContainer()} could cause the database
-         * to be closed. sqlite doesn't let a database close if there are
-         * any unfinalized statements - such as the compiled-sql objects in mCompiledQueries.
-         */
-        deallocCachedSqlStatements();
-
-        Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
-        while (iter.hasNext()) {
-            Map.Entry<SQLiteClosable, Object> entry = iter.next();
-            SQLiteClosable program = entry.getKey();
-            if (program != null) {
-                program.onAllReferencesReleasedFromContainer();
-            }
-        }
-    }
-
-    /**
-     * package level access for testing purposes
-     */
-    /* package */ void closeDatabase() throws SQLiteException {
-        try {
-            dbclose();
-        } catch (SQLiteUnfinalizedObjectsException e)  {
-            String msg = e.getMessage();
-            String[] tokens = msg.split(",", 2);
-            int stmtId = Integer.parseInt(tokens[0]);
-            // get extra info about this statement, if it is still to be released by closeClosable()
-            Iterator<Map.Entry<SQLiteClosable, Object>> iter = mPrograms.entrySet().iterator();
-            boolean found = false;
-            while (iter.hasNext()) {
-                Map.Entry<SQLiteClosable, Object> entry = iter.next();
-                SQLiteClosable program = entry.getKey();
-                if (program != null && program instanceof SQLiteProgram) {
-                    SQLiteCompiledSql compiledSql = ((SQLiteProgram)program).mCompiledSql;
-                    if (compiledSql.nStatement == stmtId) {
-                        msg = compiledSql.toString();
-                        found = true;
-                    }
-                }
-            }
-            if (!found) {
-                // the statement is already released by closeClosable(). is it waiting to be
-                // finalized?
-                if (mClosedStatementIds.contains(stmtId)) {
-                    Log.w(TAG, "this shouldn't happen. finalizing the statement now: ");
-                    closePendingStatements();
-                    // try to close the database again
-                    closeDatabase();
-                }
-            } else {
-                // the statement is not yet closed. most probably programming error in the app.
-                throw new SQLiteUnfinalizedObjectsException(
-                        "close() on database: " + getPath() +
-                        " failed due to un-close()d SQL statements: " + msg);
-            }
-        }
-    }
-
-    /**
-     * Native call to close the database.
-     */
-    private native void dbclose();
-
-    /**
-     * A callback interface for a custom sqlite3 function.
-     * This can be used to create a function that can be called from
-     * sqlite3 database triggers.
-     * @hide
-     */
-    public interface CustomFunction {
-        public void callback(String[] args);
+        dispose(false);
     }
 
     /**
      * Registers a CustomFunction callback as a function that can be called from
-     * sqlite3 database triggers.
+     * SQLite database triggers.
+     *
      * @param name the name of the sqlite3 function
      * @param numArgs the number of arguments for the function
      * @param function callback to call when the function is executed
      * @hide
      */
     public void addCustomFunction(String name, int numArgs, CustomFunction function) {
-        verifyDbIsOpen();
-        synchronized (mCustomFunctions) {
-            int ref = native_addCustomFunction(name, numArgs, function);
-            if (ref != 0) {
-                // save a reference to the function for cleanup later
-                mCustomFunctions.add(new Integer(ref));
-            } else {
-                throw new SQLiteException("failed to add custom function " + name);
-            }
+        // Create wrapper (also validates arguments).
+        SQLiteCustomFunction wrapper = new SQLiteCustomFunction(name, numArgs, function);
+
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+            mConfigurationLocked.customFunctions.add(wrapper);
+            mConnectionPoolLocked.reconfigure(mConfigurationLocked);
         }
     }
 
-    private void releaseCustomFunctions() {
-        synchronized (mCustomFunctions) {
-            for (int i = 0; i < mCustomFunctions.size(); i++) {
-                Integer function = mCustomFunctions.get(i);
-                native_releaseCustomFunction(function.intValue());
-            }
-            mCustomFunctions.clear();
-        }
-    }
-
-    // list of CustomFunction references so we can clean up when the database closes
-    private final ArrayList<Integer> mCustomFunctions =
-            new ArrayList<Integer>();
-
-    private native int native_addCustomFunction(String name, int numArgs, CustomFunction function);
-    private native void native_releaseCustomFunction(int function);
-
     /**
      * Gets the database version.
      *
@@ -1364,7 +896,7 @@
      * {@link SQLiteStatement}s are not synchronized, see the documentation for more details.
      */
     public SQLiteStatement compileStatement(String sql) throws SQLException {
-        verifyDbIsOpen();
+        throwIfNotOpen(); // fail fast
         return new SQLiteStatement(this, sql, null);
     }
 
@@ -1442,7 +974,7 @@
             boolean distinct, String table, String[] columns,
             String selection, String[] selectionArgs, String groupBy,
             String having, String orderBy, String limit) {
-        verifyDbIsOpen();
+        throwIfNotOpen(); // fail fast
         String sql = SQLiteQueryBuilder.buildQueryString(
                 distinct, table, columns, selection, groupBy, having, orderBy, limit);
 
@@ -1553,21 +1085,11 @@
     public Cursor rawQueryWithFactory(
             CursorFactory cursorFactory, String sql, String[] selectionArgs,
             String editTable) {
-        verifyDbIsOpen();
-        BlockGuard.getThreadPolicy().onReadFromDisk();
+        throwIfNotOpen(); // fail fast
 
-        SQLiteDatabase db = getDbConnection(sql);
-        SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(db, sql, editTable);
-
-        Cursor cursor = null;
-        try {
-            cursor = driver.query(
-                    cursorFactory != null ? cursorFactory : mFactory,
-                    selectionArgs);
-        } finally {
-            releaseDbConnection(db);
-        }
-        return cursor;
+        SQLiteCursorDriver driver = new SQLiteDirectCursorDriver(this, sql, editTable);
+        return driver.query(cursorFactory != null ? cursorFactory : mCursorFactory,
+                selectionArgs);
     }
 
     /**
@@ -1716,9 +1238,6 @@
         SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
         try {
             return statement.executeInsert();
-        } catch (SQLiteDatabaseCorruptException e) {
-            onCorruption();
-            throw e;
         } finally {
             statement.close();
         }
@@ -1739,9 +1258,6 @@
                 (!TextUtils.isEmpty(whereClause) ? " WHERE " + whereClause : ""), whereArgs);
         try {
             return statement.executeUpdateDelete();
-        } catch (SQLiteDatabaseCorruptException e) {
-            onCorruption();
-            throw e;
         } finally {
             statement.close();
         }
@@ -1808,9 +1324,6 @@
         SQLiteStatement statement = new SQLiteStatement(this, sql.toString(), bindArgs);
         try {
             return statement.executeUpdateDelete();
-        } catch (SQLiteDatabaseCorruptException e) {
-            onCorruption();
-            throw e;
         } finally {
             statement.close();
         }
@@ -1891,264 +1404,105 @@
 
     private int executeSql(String sql, Object[] bindArgs) throws SQLException {
         if (DatabaseUtils.getSqlStatementType(sql) == DatabaseUtils.STATEMENT_ATTACH) {
-            disableWriteAheadLogging();
-            mHasAttachedDbs = true;
+            boolean disableWal = false;
+            synchronized (mLock) {
+                if (!mHasAttachedDbsLocked) {
+                    mHasAttachedDbsLocked = true;
+                    disableWal = true;
+                }
+            }
+            if (disableWal) {
+                disableWriteAheadLogging();
+            }
         }
+
         SQLiteStatement statement = new SQLiteStatement(this, sql, bindArgs);
         try {
             return statement.executeUpdateDelete();
-        } catch (SQLiteDatabaseCorruptException e) {
-            onCorruption();
-            throw e;
         } finally {
             statement.close();
         }
     }
 
-    @Override
-    protected void finalize() throws Throwable {
-        try {
-            if (isOpen()) {
-                Log.e(TAG, "close() was never explicitly called on database '" +
-                        mPath + "' ", mStackTrace);
-                closeClosable();
-                onAllReferencesReleased();
-                releaseCustomFunctions();
-            }
-        } finally {
-            super.finalize();
-        }
-    }
-
     /**
-     * Private constructor.
+     * Returns true if the database is opened as read only.
      *
-     * @param path The full path to the database
-     * @param factory The factory to use when creating cursors, may be NULL.
-     * @param flags 0 or {@link #NO_LOCALIZED_COLLATORS}.  If the database file already
-     *              exists, mFlags will be updated appropriately.
-     * @param errorHandler The {@link DatabaseErrorHandler} to be used when sqlite reports database
-     * corruption. may be NULL.
-     * @param connectionNum 0 for main database connection handle. 1..N for pooled database
-     * connection handles.
-     */
-    private SQLiteDatabase(String path, CursorFactory factory, int flags,
-            DatabaseErrorHandler errorHandler, short connectionNum) {
-        if (path == null) {
-            throw new IllegalArgumentException("path should not be null");
-        }
-        setMaxSqlCacheSize(DEFAULT_SQL_CACHE_SIZE);
-        mFlags = flags;
-        mPath = path;
-        mStackTrace = new DatabaseObjectNotClosedException().fillInStackTrace();
-        mFactory = factory;
-        mPrograms = new WeakHashMap<SQLiteClosable,Object>();
-        // Set the DatabaseErrorHandler to be used when SQLite reports corruption.
-        // If the caller sets errorHandler = null, then use default errorhandler.
-        mErrorHandler = (errorHandler == null) ? new DefaultDatabaseErrorHandler() : errorHandler;
-        mConnectionNum = connectionNum;
-        /* sqlite soft heap limit http://www.sqlite.org/c3ref/soft_heap_limit64.html
-         * set it to 4 times the default cursor window size.
-         * TODO what is an appropriate value, considering the WAL feature which could burn
-         * a lot of memory with many connections to the database. needs testing to figure out
-         * optimal value for this.
-         */
-        int limit = Resources.getSystem().getInteger(
-                com.android.internal.R.integer.config_cursorWindowSize) * 1024 * 4;
-        native_setSqliteSoftHeapLimit(limit);
-    }
-
-    /**
-     * return whether the DB is opened as read only.
-     * @return true if DB is opened as read only
+     * @return True if database is opened as read only.
      */
     public boolean isReadOnly() {
-        return (mFlags & OPEN_READ_MASK) == OPEN_READONLY;
+        synchronized (mLock) {
+            return isReadOnlyLocked();
+        }
+    }
+
+    private boolean isReadOnlyLocked() {
+        return (mConfigurationLocked.openFlags & OPEN_READ_MASK) == OPEN_READONLY;
     }
 
     /**
-     * @return true if the DB is currently open (has not been closed)
+     * Returns true if the database is in-memory db.
+     *
+     * @return True if the database is in-memory.
+     * @hide
      */
-    public boolean isOpen() {
-        return mNativeHandle != 0;
+    public boolean isInMemoryDatabase() {
+        synchronized (mLock) {
+            return mConfigurationLocked.isInMemoryDb();
+        }
     }
 
+    /**
+     * Returns true if the database is currently open.
+     *
+     * @return True if the database is currently open (has not been closed).
+     */
+    public boolean isOpen() {
+        synchronized (mLock) {
+            return mConnectionPoolLocked != null;
+        }
+    }
+
+    /**
+     * Returns true if the new version code is greater than the current database version.
+     *
+     * @param newVersion The new version code.
+     * @return True if the new version code is greater than the current database version. 
+     */
     public boolean needUpgrade(int newVersion) {
         return newVersion > getVersion();
     }
 
     /**
-     * Getter for the path to the database file.
+     * Gets the path to the database file.
      *
-     * @return the path to our database file.
+     * @return The path to the database file.
      */
     public final String getPath() {
-        return mPath;
-    }
-
-    /* package */ void logTimeStat(String sql, long beginMillis) {
-        if (ENABLE_DB_SAMPLE) {
-            logTimeStat(sql, beginMillis, null);
+        synchronized (mLock) {
+            return mConfigurationLocked.path;
         }
     }
 
-    private void logTimeStat(String sql, long beginMillis, String prefix) {
-        // Sample fast queries in proportion to the time taken.
-        // Quantize the % first, so the logged sampling probability
-        // exactly equals the actual sampling rate for this query.
-
-        int samplePercent;
-        long durationMillis = SystemClock.uptimeMillis() - beginMillis;
-        if (durationMillis == 0 && prefix == GET_LOCK_LOG_PREFIX) {
-            // The common case is locks being uncontended.  Don't log those,
-            // even at 1%, which is our default below.
-            return;
-        }
-        if (sQueryLogTimeInMillis == 0) {
-            sQueryLogTimeInMillis = SystemProperties.getInt("db.db_operation.threshold_ms", 500);
-        }
-        if (durationMillis >= sQueryLogTimeInMillis) {
-            samplePercent = 100;
-        } else {
-            samplePercent = (int) (100 * durationMillis / sQueryLogTimeInMillis) + 1;
-            if (mRandom.nextInt(100) >= samplePercent) return;
-        }
-
-        // Note: the prefix will be "COMMIT;" or "GETLOCK:" when non-null.  We wait to do
-        // it here so we avoid allocating in the common case.
-        if (prefix != null) {
-            sql = prefix + sql;
-        }
-        if (sql.length() > QUERY_LOG_SQL_LENGTH) sql = sql.substring(0, QUERY_LOG_SQL_LENGTH);
-
-        // ActivityThread.currentPackageName() only returns non-null if the
-        // current thread is an application main thread.  This parameter tells
-        // us whether an event loop is blocked, and if so, which app it is.
-        //
-        // Sadly, there's no fast way to determine app name if this is *not* a
-        // main thread, or when we are invoked via Binder (e.g. ContentProvider).
-        // Hopefully the full path to the database will be informative enough.
-
-        String blockingPackage = AppGlobals.getInitialPackage();
-        if (blockingPackage == null) blockingPackage = "";
-
-        EventLog.writeEvent(
-            EVENT_DB_OPERATION,
-            getPathForLogs(),
-            sql,
-            durationMillis,
-            blockingPackage,
-            samplePercent);
-    }
-
-    /**
-     * Removes email addresses from database filenames before they're
-     * logged to the EventLog where otherwise apps could potentially
-     * read them.
-     */
-    private String getPathForLogs() {
-        if (mPathForLogs != null) {
-            return mPathForLogs;
-        }
-        if (mPath == null) {
-            return null;
-        }
-        if (mPath.indexOf('@') == -1) {
-            mPathForLogs = mPath;
-        } else {
-            mPathForLogs = EMAIL_IN_DB_PATTERN.matcher(mPath).replaceAll("XX@YY");
-        }
-        return mPathForLogs;
-    }
-
     /**
      * Sets the locale for this database.  Does nothing if this database has
      * the NO_LOCALIZED_COLLATORS flag set or was opened read only.
+     *
+     * @param locale The new locale.
+     *
      * @throws SQLException if the locale could not be set.  The most common reason
      * for this is that there is no collator available for the locale you requested.
      * In this case the database remains unchanged.
      */
     public void setLocale(Locale locale) {
-        lock();
-        try {
-            native_setLocale(locale.toString(), mFlags);
-        } finally {
-            unlock();
-        }
-    }
-
-    /* package */ void verifyDbIsOpen() {
-        if (!isOpen()) {
-            throw new IllegalStateException("database " + getPath() + " (conn# " +
-                    mConnectionNum + ") already closed");
-        }
-    }
-
-    /* package */ void verifyLockOwner() {
-        verifyDbIsOpen();
-        if (mLockingEnabled && !isDbLockedByCurrentThread()) {
-            throw new IllegalStateException("Don't have database lock!");
-        }
-    }
-
-    /**
-     * Adds the given SQL and its compiled-statement-id-returned-by-sqlite to the
-     * cache of compiledQueries attached to 'this'.
-     * <p>
-     * If there is already a {@link SQLiteCompiledSql} in compiledQueries for the given SQL,
-     * the new {@link SQLiteCompiledSql} object is NOT inserted into the cache (i.e.,the current
-     * mapping is NOT replaced with the new mapping).
-     */
-    /* package */ synchronized void addToCompiledQueries(
-            String sql, SQLiteCompiledSql compiledStatement) {
-        // don't insert the new mapping if a mapping already exists
-        if (mCompiledQueries.get(sql) != null) {
-            return;
+        if (locale == null) {
+            throw new IllegalArgumentException("locale must not be null.");
         }
 
-        int maxCacheSz = (mConnectionNum == 0) ? mCompiledQueries.maxSize() :
-                mParentConnObj.mCompiledQueries.maxSize();
-
-        if (SQLiteDebug.DEBUG_SQL_CACHE) {
-            boolean printWarning = (mConnectionNum == 0)
-                    ? (!mCacheFullWarning && mCompiledQueries.size() == maxCacheSz)
-                    : (!mParentConnObj.mCacheFullWarning &&
-                    mParentConnObj.mCompiledQueries.size() == maxCacheSz);
-            if (printWarning) {
-                /*
-                 * cache size is not enough for this app. log a warning.
-                 * chances are it is NOT using ? for bindargs - or cachesize is too small.
-                 */
-                Log.w(TAG, "Reached MAX size for compiled-sql statement cache for database " +
-                        getPath() + ". Use setMaxSqlCacheSize() to increase cachesize. ");
-                mCacheFullWarning = true;
-                Log.d(TAG, "Here are the SQL statements in Cache of database: " + mPath);
-                for (String s : mCompiledQueries.snapshot().keySet()) {
-                    Log.d(TAG, "Sql statement in Cache: " + s);
-                }
-            }
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+            mConfigurationLocked.locale = locale;
+            mConnectionPoolLocked.reconfigure(mConfigurationLocked);
         }
-        /* add the given SQLiteCompiledSql compiledStatement to cache.
-         * no need to worry about the cache size - because {@link #mCompiledQueries}
-         * self-limits its size.
-         */
-        mCompiledQueries.put(sql, compiledStatement);
-    }
-
-    /** package-level access for testing purposes */
-    /* package */ synchronized void deallocCachedSqlStatements() {
-        for (SQLiteCompiledSql compiledSql : mCompiledQueries.snapshot().values()) {
-            compiledSql.releaseSqlStatement();
-        }
-        mCompiledQueries.evictAll();
-    }
-
-    /**
-     * From the compiledQueries cache, returns the compiled-statement-id for the given SQL.
-     * Returns null, if not found in the cache.
-     */
-    /* package */ synchronized SQLiteCompiledSql getCompiledStatementForSql(String sql) {
-        return mCompiledQueries.get(sql);
     }
 
     /**
@@ -2162,115 +1516,21 @@
      * This method is thread-safe.
      *
      * @param cacheSize the size of the cache. can be (0 to {@link #MAX_SQL_CACHE_SIZE})
-     * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE} or
-     * the value set with previous setMaxSqlCacheSize() call.
+     * @throws IllegalStateException if input cacheSize > {@link #MAX_SQL_CACHE_SIZE}.
      */
     public void setMaxSqlCacheSize(int cacheSize) {
-        synchronized (this) {
-            LruCache<String, SQLiteCompiledSql> oldCompiledQueries = mCompiledQueries;
-            if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
-                throw new IllegalStateException(
-                        "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
-            } else if (oldCompiledQueries != null && cacheSize < oldCompiledQueries.maxSize()) {
-                throw new IllegalStateException("cannot set cacheSize to a value less than the "
-                        + "value set with previous setMaxSqlCacheSize() call.");
-            }
-            mCompiledQueries = new LruCache<String, SQLiteCompiledSql>(cacheSize) {
-                @Override
-                protected void entryRemoved(boolean evicted, String key, SQLiteCompiledSql oldValue,
-                        SQLiteCompiledSql newValue) {
-                    verifyLockOwner();
-                    oldValue.releaseIfNotInUse();
-                }
-            };
-            if (oldCompiledQueries != null) {
-                for (Map.Entry<String, SQLiteCompiledSql> entry
-                        : oldCompiledQueries.snapshot().entrySet()) {
-                    mCompiledQueries.put(entry.getKey(), entry.getValue());
-                }
-            }
+        if (cacheSize > MAX_SQL_CACHE_SIZE || cacheSize < 0) {
+            throw new IllegalStateException(
+                    "expected value between 0 and " + MAX_SQL_CACHE_SIZE);
         }
-    }
 
-    /* package */ synchronized boolean isInStatementCache(String sql) {
-        return mCompiledQueries.get(sql) != null;
-    }
-
-    /* package */ synchronized void releaseCompiledSqlObj(
-            String sql, SQLiteCompiledSql compiledSql) {
-        if (mCompiledQueries.get(sql) == compiledSql) {
-            // it is in cache - reset its inUse flag
-            compiledSql.release();
-        } else {
-            // it is NOT in cache. finalize it.
-            compiledSql.releaseSqlStatement();
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+            mConfigurationLocked.maxSqlCacheSize = cacheSize;
+            mConnectionPoolLocked.reconfigure(mConfigurationLocked);
         }
     }
 
-    private synchronized int getCacheHitNum() {
-        return mCompiledQueries.hitCount();
-    }
-
-    private synchronized int getCacheMissNum() {
-        return mCompiledQueries.missCount();
-    }
-
-    private synchronized int getCachesize() {
-        return mCompiledQueries.size();
-    }
-
-    /* package */ void finalizeStatementLater(int id) {
-        if (!isOpen()) {
-            // database already closed. this statement will already have been finalized.
-            return;
-        }
-        synchronized(mClosedStatementIds) {
-            if (mClosedStatementIds.contains(id)) {
-                // this statement id is already queued up for finalization.
-                return;
-            }
-            mClosedStatementIds.add(id);
-        }
-    }
-
-    /* package */ boolean isInQueueOfStatementsToBeFinalized(int id) {
-        if (!isOpen()) {
-            // database already closed. this statement will already have been finalized.
-            // return true so that the caller doesn't have to worry about finalizing this statement.
-            return true;
-        }
-        synchronized(mClosedStatementIds) {
-            return mClosedStatementIds.contains(id);
-        }
-    }
-
-    /* package */ void closePendingStatements() {
-        if (!isOpen()) {
-            // since this database is already closed, no need to finalize anything.
-            mClosedStatementIds.clear();
-            return;
-        }
-        verifyLockOwner();
-        /* to minimize synchronization on mClosedStatementIds, make a copy of the list */
-        ArrayList<Integer> list = new ArrayList<Integer>(mClosedStatementIds.size());
-        synchronized(mClosedStatementIds) {
-            list.addAll(mClosedStatementIds);
-            mClosedStatementIds.clear();
-        }
-        // finalize all the statements from the copied list
-        int size = list.size();
-        for (int i = 0; i < size; i++) {
-            native_finalize(list.get(i));
-        }
-    }
-
-    /**
-     * for testing only
-     */
-    /* package */ ArrayList<Integer> getQueuedUpStmtList() {
-        return mClosedStatementIds;
-    }
-
     /**
      * This method enables parallel execution of queries from multiple threads on the same database.
      * It does this by opening multiple handles to the database and using a different
@@ -2314,37 +1574,43 @@
      * @return true if write-ahead-logging is set. false otherwise
      */
     public boolean enableWriteAheadLogging() {
-        // make sure the database is not READONLY. WAL doesn't make sense for readonly-databases.
-        if (isReadOnly()) {
-            return false;
-        }
-        // acquire lock - no that no other thread is enabling WAL at the same time
-        lock();
-        try {
-            if (mConnectionPool != null) {
-                // already enabled
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if (mIsWALEnabledLocked) {
                 return true;
             }
-            if (mPath.equalsIgnoreCase(MEMORY_DB_PATH)) {
+
+            if (isReadOnlyLocked()) {
+                // WAL doesn't make sense for readonly-databases.
+                // TODO: True, but connection pooling does still make sense...
+                return false;
+            }
+
+            if (mConfigurationLocked.isInMemoryDb()) {
                 Log.i(TAG, "can't enable WAL for memory databases.");
                 return false;
             }
 
             // make sure this database has NO attached databases because sqlite's write-ahead-logging
             // doesn't work for databases with attached databases
-            if (mHasAttachedDbs) {
+            if (mHasAttachedDbsLocked) {
                 if (Log.isLoggable(TAG, Log.DEBUG)) {
-                    Log.d(TAG,
-                            "this database: " + mPath + " has attached databases. can't  enable WAL.");
+                    Log.d(TAG, "this database: " + mConfigurationLocked.label
+                            + " has attached databases. can't  enable WAL.");
                 }
                 return false;
             }
-            mConnectionPool = new DatabaseConnectionPool(this);
-            setJournalMode(mPath, "WAL");
-            return true;
-        } finally {
-            unlock();
+
+            mIsWALEnabledLocked = true;
+            mConfigurationLocked.maxConnectionPoolSize = Math.max(2,
+                    Resources.getSystem().getInteger(
+                            com.android.internal.R.integer.db_connection_pool_size));
+            mConnectionPoolLocked.reconfigure(mConfigurationLocked);
         }
+
+        setJournalMode("WAL");
+        return true;
     }
 
     /**
@@ -2352,178 +1618,68 @@
      * @hide
      */
     public void disableWriteAheadLogging() {
-        // grab database lock so that writeAheadLogging is not disabled from 2 different threads
-        // at the same time
-        lock();
-        try {
-            if (mConnectionPool == null) {
-                return; // already disabled
+        synchronized (mLock) {
+            throwIfNotOpenLocked();
+
+            if (!mIsWALEnabledLocked) {
+                return;
             }
-            mConnectionPool.close();
-            setJournalMode(mPath, "TRUNCATE");
-            mConnectionPool = null;
-        } finally {
-            unlock();
-        }
-    }
 
-    /* package */ SQLiteDatabase getDatabaseHandle(String sql) {
-        if (isPooledConnection()) {
-            // this is a pooled database connection
-            // use it if it is open AND if I am not currently part of a transaction
-            if (isOpen() && !amIInTransaction()) {
-                // TODO: use another connection from the pool
-                // if this connection is currently in use by some other thread
-                // AND if there are free connections in the pool
-                return this;
-            } else {
-                // the pooled connection is not open! could have been closed either due
-                // to corruption on this or some other connection to the database
-                // OR, maybe the connection pool is disabled after this connection has been
-                // allocated to me. try to get some other pooled or main database connection
-                return getParentDbConnObj().getDbConnection(sql);
-            }
-        } else {
-            // this is NOT a pooled connection. can we get one?
-            return getDbConnection(sql);
-        }
-    }
-
-    /* package */ SQLiteDatabase createPoolConnection(short connectionNum) {
-        SQLiteDatabase db = openDatabase(mPath, mFactory, mFlags, mErrorHandler, connectionNum);
-        db.mParentConnObj = this;
-        return db;
-    }
-
-    private synchronized SQLiteDatabase getParentDbConnObj() {
-        return mParentConnObj;
-    }
-
-    private boolean isPooledConnection() {
-        return this.mConnectionNum > 0;
-    }
-
-    /* package */ SQLiteDatabase getDbConnection(String sql) {
-        verifyDbIsOpen();
-        // this method should always be called with main database connection handle.
-        // the only time when it is called with pooled database connection handle is
-        // corruption occurs while trying to open a pooled database connection handle.
-        // in that case, simply return 'this' handle
-        if (isPooledConnection()) {
-            return this;
+            mIsWALEnabledLocked = false;
+            mConfigurationLocked.maxConnectionPoolSize = 1;
+            mConnectionPoolLocked.reconfigure(mConfigurationLocked);
         }
 
-        // use the current connection handle if
-        // 1. if the caller is part of the ongoing transaction, if any
-        // 2. OR, if there is NO connection handle pool setup
-        if (amIInTransaction() || mConnectionPool == null) {
-            return this;
-        } else {
-            // get a connection handle from the pool
-            if (Log.isLoggable(TAG, Log.DEBUG)) {
-                assert mConnectionPool != null;
-                Log.i(TAG, mConnectionPool.toString());
-            }
-            return mConnectionPool.get(sql);
-        }
-    }
-
-    private void releaseDbConnection(SQLiteDatabase db) {
-        // ignore this release call if
-        // 1. the database is closed
-        // 2. OR, if db is NOT a pooled connection handle
-        // 3. OR, if the database being released is same as 'this' (this condition means
-        //     that we should always be releasing a pooled connection handle by calling this method
-        //     from the 'main' connection handle
-        if (!isOpen() || !db.isPooledConnection() || (db == this)) {
-            return;
-        }
-        if (Log.isLoggable(TAG, Log.DEBUG)) {
-            assert isPooledConnection();
-            assert mConnectionPool != null;
-            Log.d(TAG, "releaseDbConnection threadid = " + Thread.currentThread().getId() +
-                    ", releasing # " + db.mConnectionNum + ", " + getPath());
-        }
-        mConnectionPool.release(db);
+        setJournalMode("TRUNCATE");
     }
 
     /**
-     * this method is used to collect data about ALL open databases in the current process.
-     * bugreport is a user of this data.
+     * Collect statistics about all open databases in the current process.
+     * Used by bug report.
      */
-    /* package */ static ArrayList<DbStats> getDbStats() {
+    static ArrayList<DbStats> getDbStats() {
         ArrayList<DbStats> dbStatsList = new ArrayList<DbStats>();
-        // make a local copy of mActiveDatabases - so that this method is not competing
-        // for synchronization lock on mActiveDatabases
-        ArrayList<WeakReference<SQLiteDatabase>> tempList;
-        synchronized(mActiveDatabases) {
-            tempList = (ArrayList<WeakReference<SQLiteDatabase>>)mActiveDatabases.clone();
-        }
-        for (WeakReference<SQLiteDatabase> w : tempList) {
-            SQLiteDatabase db = w.get();
-            if (db == null || !db.isOpen()) {
-                continue;
-            }
-
-            try {
-                // get SQLITE_DBSTATUS_LOOKASIDE_USED for the db
-                int lookasideUsed = db.native_getDbLookaside();
-
-                // get the lastnode of the dbname
-                String path = db.getPath();
-                int indx = path.lastIndexOf("/");
-                String lastnode = path.substring((indx != -1) ? ++indx : 0);
-
-                // get list of attached dbs and for each db, get its size and pagesize
-                List<Pair<String, String>> attachedDbs = db.getAttachedDbs();
-                if (attachedDbs == null) {
-                    continue;
-                }
-                for (int i = 0; i < attachedDbs.size(); i++) {
-                    Pair<String, String> p = attachedDbs.get(i);
-                    long pageCount = DatabaseUtils.longForQuery(db, "PRAGMA " + p.first
-                            + ".page_count;", null);
-
-                    // first entry in the attached db list is always the main database
-                    // don't worry about prefixing the dbname with "main"
-                    String dbName;
-                    if (i == 0) {
-                        dbName = lastnode;
-                    } else {
-                        // lookaside is only relevant for the main db
-                        lookasideUsed = 0;
-                        dbName = "  (attached) " + p.first;
-                        // if the attached db has a path, attach the lastnode from the path to above
-                        if (p.second.trim().length() > 0) {
-                            int idx = p.second.lastIndexOf("/");
-                            dbName += " : " + p.second.substring((idx != -1) ? ++idx : 0);
-                        }
-                    }
-                    if (pageCount > 0) {
-                        dbStatsList.add(new DbStats(dbName, pageCount, db.getPageSize(),
-                                lookasideUsed, db.getCacheHitNum(), db.getCacheMissNum(),
-                                db.getCachesize()));
-                    }
-                }
-                // if there are pooled connections, return the cache stats for them also.
-                // while we are trying to query the pooled connections for stats, some other thread
-                // could be disabling conneciton pool. so, grab a reference to the connection pool.
-                DatabaseConnectionPool connPool = db.mConnectionPool;
-                if (connPool != null) {
-                    for (SQLiteDatabase pDb : connPool.getConnectionList()) {
-                        dbStatsList.add(new DbStats("(pooled # " + pDb.mConnectionNum + ") "
-                                + lastnode, 0, 0, 0, pDb.getCacheHitNum(),
-                                pDb.getCacheMissNum(), pDb.getCachesize()));
-                    }
-                }
-            } catch (SQLiteException e) {
-                // ignore. we don't care about exceptions when we are taking adb
-                // bugreport!
-            }
+        for (SQLiteDatabase db : getActiveDatabases()) {
+            db.collectDbStats(dbStatsList);
         }
         return dbStatsList;
     }
 
+    private void collectDbStats(ArrayList<DbStats> dbStatsList) {
+        synchronized (mLock) {
+            if (mConnectionPoolLocked != null) {
+                mConnectionPoolLocked.collectDbStats(dbStatsList);
+            }
+        }
+    }
+
+    private static ArrayList<SQLiteDatabase> getActiveDatabases() {
+        ArrayList<SQLiteDatabase> databases = new ArrayList<SQLiteDatabase>();
+        synchronized (sActiveDatabases) {
+            databases.addAll(sActiveDatabases.keySet());
+        }
+        return databases;
+    }
+
+    /**
+     * Dump detailed information about all open databases in the current process.
+     * Used by bug report.
+     */
+    static void dumpAll(Printer printer) {
+        for (SQLiteDatabase db : getActiveDatabases()) {
+            db.dump(printer);
+        }
+    }
+
+    private void dump(Printer printer) {
+        synchronized (mLock) {
+            if (mConnectionPoolLocked != null) {
+                printer.println("");
+                mConnectionPoolLocked.dump(printer);
+            }
+        }
+    }
+
     /**
      * Returns list of full pathnames of all attached databases including the main database
      * by executing 'pragma database_list' on the database.
@@ -2532,23 +1688,27 @@
      * is not open.
      */
     public List<Pair<String, String>> getAttachedDbs() {
-        if (!isOpen()) {
-            return null;
-        }
         ArrayList<Pair<String, String>> attachedDbs = new ArrayList<Pair<String, String>>();
-        if (!mHasAttachedDbs) {
-            // No attached databases.
-            // There is a small window where attached databases exist but this flag is not set yet.
-            // This can occur when this thread is in a race condition with another thread
-            // that is executing the SQL statement: "attach database <blah> as <foo>"
-            // If this thread is NOT ok with such a race condition (and thus possibly not receive
-            // the entire list of attached databases), then the caller should ensure that no thread
-            // is executing any SQL statements while a thread is calling this method.
-            // Typically, this method is called when 'adb bugreport' is done or the caller wants to
-            // collect stats on the database and all its attached databases.
-            attachedDbs.add(new Pair<String, String>("main", mPath));
-            return attachedDbs;
+        synchronized (mLock) {
+            if (mConnectionPoolLocked == null) {
+                return null; // not open
+            }
+
+            if (!mHasAttachedDbsLocked) {
+                // No attached databases.
+                // There is a small window where attached databases exist but this flag is not
+                // set yet.  This can occur when this thread is in a race condition with another
+                // thread that is executing the SQL statement: "attach database <blah> as <foo>"
+                // If this thread is NOT ok with such a race condition (and thus possibly not
+                // receivethe entire list of attached databases), then the caller should ensure
+                // that no thread is executing any SQL statements while a thread is calling this
+                // method.  Typically, this method is called when 'adb bugreport' is done or the
+                // caller wants to collect stats on the database and all its attached databases.
+                attachedDbs.add(new Pair<String, String>("main", mConfigurationLocked.path));
+                return attachedDbs;
+            }
         }
+
         // has attached databases. query sqlite to get the list of attached databases.
         Cursor c = null;
         try {
@@ -2583,7 +1743,8 @@
      * false otherwise.
      */
     public boolean isDatabaseIntegrityOk() {
-        verifyDbIsOpen();
+        throwIfNotOpen(); // fail fast
+
         List<Pair<String, String>> attachedDbs = null;
         try {
             attachedDbs = getAttachedDbs();
@@ -2594,8 +1755,9 @@
         } catch (SQLiteException e) {
             // can't get attachedDb list. do integrity check on the main database
             attachedDbs = new ArrayList<Pair<String, String>>();
-            attachedDbs.add(new Pair<String, String>("main", this.mPath));
+            attachedDbs.add(new Pair<String, String>("main", getPath()));
         }
+
         for (int i = 0; i < attachedDbs.size(); i++) {
             Pair<String, String> p = attachedDbs.get(i);
             SQLiteStatement prog = null;
@@ -2615,59 +1777,64 @@
     }
 
     /**
-     * Native call to open the database.
+     * Prevent other threads from using the database's primary connection.
      *
-     * @param path The full path to the database
-     */
-    private native void dbopen(String path, int flags);
-
-    /**
-     * Native call to setup tracing of all SQL statements
+     * This method is only used by {@link SQLiteOpenHelper} when transitioning from
+     * a readable to a writable database.  It should not be used in any other way.
      *
-     * @param path the full path to the database
-     * @param connectionNum connection number: 0 - N, where the main database
-     *            connection handle is numbered 0 and the connection handles in the connection
-     *            pool are numbered 1..N.
+     * @see #unlockPrimaryConnection()
      */
-    private native void enableSqlTracing(String path, short connectionNum);
+    void lockPrimaryConnection() {
+        getThreadSession().beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED,
+                null, SQLiteConnectionPool.CONNECTION_FLAG_PRIMARY_CONNECTION_AFFINITY);
+    }
 
     /**
-     * Native call to setup profiling of all SQL statements.
-     * currently, sqlite's profiling = printing of execution-time
-     * (wall-clock time) of each of the SQL statements, as they
-     * are executed.
+     * Allow other threads to use the database's primary connection.
      *
-     * @param path the full path to the database
-     * @param connectionNum connection number: 0 - N, where the main database
-     *            connection handle is numbered 0 and the connection handles in the connection
-     *            pool are numbered 1..N.
+     * @see #lockPrimaryConnection()
      */
-    private native void enableSqlProfiling(String path, short connectionNum);
+    void unlockPrimaryConnection() {
+        getThreadSession().endTransaction();
+    }
+
+    @Override
+    public String toString() {
+        return "SQLiteDatabase: " + getPath();
+    }
+
+    private void throwIfNotOpen() {
+        synchronized (mConnectionPoolLocked) {
+            throwIfNotOpenLocked();
+        }
+    }
+
+    private void throwIfNotOpenLocked() {
+        if (mConnectionPoolLocked == null) {
+            throw new IllegalStateException("The database '" + mConfigurationLocked.label
+                    + "' is not open.");
+        }
+    }
 
     /**
-     * Native call to set the locale.  {@link #lock} must be held when calling
-     * this method.
-     * @throws SQLException
+     * Used to allow returning sub-classes of {@link Cursor} when calling query.
      */
-    private native void native_setLocale(String loc, int flags);
+    public interface CursorFactory {
+        /**
+         * See {@link SQLiteCursor#SQLiteCursor(SQLiteCursorDriver, String, SQLiteQuery)}.
+         */
+        public Cursor newCursor(SQLiteDatabase db,
+                SQLiteCursorDriver masterQuery, String editTable,
+                SQLiteQuery query);
+    }
 
     /**
-     * return the SQLITE_DBSTATUS_LOOKASIDE_USED documented here
-     * http://www.sqlite.org/c3ref/c_dbstatus_lookaside_used.html
-     * @return int value of SQLITE_DBSTATUS_LOOKASIDE_USED
+     * A callback interface for a custom sqlite3 function.
+     * This can be used to create a function that can be called from
+     * sqlite3 database triggers.
+     * @hide
      */
-    private native int native_getDbLookaside();
-
-    /**
-     * finalizes the given statement id.
-     *
-     * @param statementId statement to be finzlied by sqlite
-     */
-    private final native void native_finalize(int statementId);
-
-    /**
-     * set sqlite soft heap limit
-     * http://www.sqlite.org/c3ref/soft_heap_limit64.html
-     */
-    private native void native_setSqliteSoftHeapLimit(int softHeapLimit);
+    public interface CustomFunction {
+        public void callback(String[] args);
+    }
 }
diff --git a/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
new file mode 100644
index 0000000..bc79ad3
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteDatabaseConfiguration.java
@@ -0,0 +1,167 @@
+/*
+ * 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 android.database.sqlite;
+
+import java.util.ArrayList;
+import java.util.Locale;
+import java.util.regex.Pattern;
+
+/**
+ * Describes how to configure a database.
+ * <p>
+ * The purpose of this object is to keep track of all of the little
+ * configuration settings that are applied to a database after it
+ * is opened so that they can be applied to all connections in the
+ * connection pool uniformly.
+ * </p><p>
+ * Each connection maintains its own copy of this object so it can
+ * keep track of which settings have already been applied.
+ * </p>
+ *
+ * @hide
+ */
+public final class SQLiteDatabaseConfiguration {
+    // The pattern we use to strip email addresses from database paths
+    // when constructing a label to use in log messages.
+    private static final Pattern EMAIL_IN_DB_PATTERN =
+            Pattern.compile("[\\w\\.\\-]+@[\\w\\.\\-]+");
+
+    /**
+     * Special path used by in-memory databases.
+     */
+    public static final String MEMORY_DB_PATH = ":memory:";
+
+    /**
+     * The database path.
+     */
+    public final String path;
+
+    /**
+     * The flags used to open the database.
+     */
+    public final int openFlags;
+
+    /**
+     * The label to use to describe the database when it appears in logs.
+     * This is derived from the path but is stripped to remove PII.
+     */
+    public final String label;
+
+    /**
+     * The maximum number of connections to retain in the connection pool.
+     * Must be at least 1.
+     *
+     * Default is 1.
+     */
+    public int maxConnectionPoolSize;
+
+    /**
+     * The maximum size of the prepared statement cache for each database connection.
+     * Must be non-negative.
+     *
+     * Default is 25.
+     */
+    public int maxSqlCacheSize;
+
+    /**
+     * The database locale.
+     *
+     * Default is the value returned by {@link Locale#getDefault()}.
+     */
+    public Locale locale;
+
+    /**
+     * The custom functions to register.
+     */
+    public final ArrayList<SQLiteCustomFunction> customFunctions =
+            new ArrayList<SQLiteCustomFunction>();
+
+    /**
+     * Creates a database configuration with the required parameters for opening a
+     * database and default values for all other parameters.
+     *
+     * @param path The database path.
+     * @param openFlags Open flags for the database, such as {@link SQLiteDatabase#OPEN_READWRITE}.
+     */
+    public SQLiteDatabaseConfiguration(String path, int openFlags) {
+        if (path == null) {
+            throw new IllegalArgumentException("path must not be null.");
+        }
+
+        this.path = path;
+        this.openFlags = openFlags;
+        label = stripPathForLogs(path);
+
+        // Set default values for optional parameters.
+        maxConnectionPoolSize = 1;
+        maxSqlCacheSize = 25;
+        locale = Locale.getDefault();
+    }
+
+    /**
+     * Creates a database configuration as a copy of another configuration.
+     *
+     * @param other The other configuration.
+     */
+    public SQLiteDatabaseConfiguration(SQLiteDatabaseConfiguration other) {
+        if (other == null) {
+            throw new IllegalArgumentException("other must not be null.");
+        }
+
+        this.path = other.path;
+        this.openFlags = other.openFlags;
+        this.label = other.label;
+        updateParametersFrom(other);
+    }
+
+    /**
+     * Updates the non-immutable parameters of this configuration object
+     * from the other configuration object.
+     *
+     * @param other The object from which to copy the parameters.
+     */
+    public void updateParametersFrom(SQLiteDatabaseConfiguration other) {
+        if (other == null) {
+            throw new IllegalArgumentException("other must not be null.");
+        }
+        if (!path.equals(other.path) || openFlags != other.openFlags) {
+            throw new IllegalArgumentException("other configuration must refer to "
+                    + "the same database.");
+        }
+
+        maxConnectionPoolSize = other.maxConnectionPoolSize;
+        maxSqlCacheSize = other.maxSqlCacheSize;
+        locale = other.locale;
+        customFunctions.clear();
+        customFunctions.addAll(other.customFunctions);
+    }
+
+    /**
+     * Returns true if the database is in-memory.
+     * @return True if the database is in-memory.
+     */
+    public boolean isInMemoryDb() {
+        return path.equalsIgnoreCase(MEMORY_DB_PATH);
+    }
+
+    private static String stripPathForLogs(String path) {
+        if (path.indexOf('@') == -1) {
+            return path;
+        }
+        return EMAIL_IN_DB_PATTERN.matcher(path).replaceAll("XX@YY");
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteDebug.java b/core/java/android/database/sqlite/SQLiteDebug.java
index 029bb4a8..d87c3e4 100644
--- a/core/java/android/database/sqlite/SQLiteDebug.java
+++ b/core/java/android/database/sqlite/SQLiteDebug.java
@@ -30,6 +30,12 @@
  */
 public final class SQLiteDebug {
     /**
+     * Controls the printing of informational SQL log messages.
+     */
+    public static final boolean DEBUG_SQL_LOG =
+            Log.isLoggable("SQLiteLog", Log.VERBOSE);
+
+    /**
      * Controls the printing of SQL statements as they are executed.
      */
     public static final boolean DEBUG_SQL_STATEMENTS =
@@ -186,6 +192,7 @@
      * @param printer The printer for dumping database state.
      */
     public static void dump(Printer printer, String[] args) {
+        SQLiteDatabase.dumpAll(printer);
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
index a5e762e..52fd1d2 100644
--- a/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
+++ b/core/java/android/database/sqlite/SQLiteDirectCursorDriver.java
@@ -25,10 +25,9 @@
  * @hide
  */
 public class SQLiteDirectCursorDriver implements SQLiteCursorDriver {
-    private String mEditTable; 
-    private SQLiteDatabase mDatabase;
-    private Cursor mCursor;
-    private String mSql;
+    private final SQLiteDatabase mDatabase;
+    private final String mEditTable; 
+    private final String mSql;
     private SQLiteQuery mQuery;
 
     public SQLiteDirectCursorDriver(SQLiteDatabase db, String sql, String editTable) {
@@ -38,33 +37,27 @@
     }
 
     public Cursor query(CursorFactory factory, String[] selectionArgs) {
-        // Compile the query
-        SQLiteQuery query = null;
-
+        final SQLiteQuery query = new SQLiteQuery(mDatabase, mSql);
+        final Cursor cursor;
         try {
-            mDatabase.lock(mSql);
-            mDatabase.closePendingStatements();
-            query = new SQLiteQuery(mDatabase, mSql, 0, selectionArgs);
+            query.bindAllArgsAsStrings(selectionArgs);
 
-            // Create the cursor
             if (factory == null) {
-                mCursor = new SQLiteCursor(this, mEditTable, query);
+                cursor = new SQLiteCursor(this, mEditTable, query);
             } else {
-                mCursor = factory.newCursor(mDatabase, this, mEditTable, query);
+                cursor = factory.newCursor(mDatabase, this, mEditTable, query);
             }
-
-            mQuery = query;
-            query = null;
-            return mCursor;
-        } finally {
-            // Make sure this object is cleaned up if something happens
-            if (query != null) query.close();
-            mDatabase.unlock();
+        } catch (RuntimeException ex) {
+            query.close();
+            throw ex;
         }
+
+        mQuery = query;
+        return cursor;
     }
 
     public void cursorClosed() {
-        mCursor = null;
+        // Do nothing
     }
 
     public void setBindArguments(String[] bindArgs) {
diff --git a/core/java/android/database/sqlite/SQLiteGlobal.java b/core/java/android/database/sqlite/SQLiteGlobal.java
new file mode 100644
index 0000000..5e129be
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteGlobal.java
@@ -0,0 +1,89 @@
+/*
+ * 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 android.database.sqlite;
+
+import android.os.StatFs;
+
+/**
+ * Provides access to SQLite functions that affect all database connection,
+ * such as memory management.
+ *
+ * @hide
+ */
+public final class SQLiteGlobal {
+    private static final String TAG = "SQLiteGlobal";
+
+    private static final Object sLock = new Object();
+    private static boolean sInitialized;
+    private static int sSoftHeapLimit;
+    private static int sDefaultPageSize;
+
+    private static native void nativeConfig(boolean verboseLog, int softHeapLimit);
+    private static native int nativeReleaseMemory(int bytesToFree);
+
+    private SQLiteGlobal() {
+    }
+
+    /**
+     * Initializes global SQLite settings the first time it is called.
+     * Should be called before opening the first (or any) database.
+     * Does nothing on repeated subsequent calls.
+     */
+    public static void initializeOnce() {
+        synchronized (sLock) {
+            if (!sInitialized) {
+                sInitialized = true;
+
+                // Limit to 8MB for now.  This is 4 times the maximum cursor window
+                // size, as has been used by the original code in SQLiteDatabase for
+                // a long time.
+                // TODO: We really do need to test whether this helps or hurts us.
+                sSoftHeapLimit = 8 * 1024 * 1024;
+
+                // Configure SQLite.
+                nativeConfig(SQLiteDebug.DEBUG_SQL_LOG, sSoftHeapLimit);
+            }
+        }
+    }
+
+    /**
+     * Attempts to release memory by pruning the SQLite page cache and other
+     * internal data structures.
+     *
+     * @return The number of bytes that were freed.
+     */
+    public static int releaseMemory() {
+        synchronized (sLock) {
+            if (!sInitialized) {
+                return 0;
+            }
+            return nativeReleaseMemory(sSoftHeapLimit);
+        }
+    }
+
+    /**
+     * Gets the default page size to use when creating a database.
+     */
+    public static int getDefaultPageSize() {
+        synchronized (sLock) {
+            if (sDefaultPageSize == 0) {
+                sDefaultPageSize = new StatFs("/data").getBlockSize();
+            }
+            return sDefaultPageSize;
+        }
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 56cf948..31da7e4 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -143,12 +143,14 @@
         // If we have a read-only database open, someone could be using it
         // (though they shouldn't), which would cause a lock to be held on
         // the file, and our attempts to open the database read-write would
-        // fail waiting for the file lock.  To prevent that, we acquire the
-        // lock on the read-only database, which shuts out other users.
+        // fail waiting for the file lock.  To prevent that, we acquire a lock
+        // on the read-only database, which shuts out other users.
 
         boolean success = false;
         SQLiteDatabase db = null;
-        if (mDatabase != null) mDatabase.lock();
+        if (mDatabase != null) {
+            mDatabase.lockPrimaryConnection();
+        }
         try {
             mIsInitializing = true;
             if (mName == null) {
@@ -185,11 +187,13 @@
             if (success) {
                 if (mDatabase != null) {
                     try { mDatabase.close(); } catch (Exception e) { }
-                    mDatabase.unlock();
+                    mDatabase.unlockPrimaryConnection();
                 }
                 mDatabase = db;
             } else {
-                if (mDatabase != null) mDatabase.unlock();
+                if (mDatabase != null) {
+                    mDatabase.unlockPrimaryConnection();
+                }
                 if (db != null) db.close();
             }
         }
diff --git a/core/java/android/database/sqlite/SQLiteProgram.java b/core/java/android/database/sqlite/SQLiteProgram.java
index 2bbc6d7..8194458 100644
--- a/core/java/android/database/sqlite/SQLiteProgram.java
+++ b/core/java/android/database/sqlite/SQLiteProgram.java
@@ -17,225 +17,104 @@
 package android.database.sqlite;
 
 import android.database.DatabaseUtils;
-import android.database.Cursor;
 
-import java.util.HashMap;
+import java.util.Arrays;
 
 /**
  * A base class for compiled SQLite programs.
- *<p>
- * SQLiteProgram is NOT internally synchronized so code using a SQLiteProgram from multiple
- * threads should perform its own synchronization when using the SQLiteProgram.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
  */
 public abstract class SQLiteProgram extends SQLiteClosable {
+    private static final String[] EMPTY_STRING_ARRAY = new String[0];
 
-    private static final String TAG = "SQLiteProgram";
+    private final SQLiteDatabase mDatabase;
+    private final String mSql;
+    private final boolean mReadOnly;
+    private final String[] mColumnNames;
+    private final int mNumParameters;
+    private final Object[] mBindArgs;
 
-    /** The database this program is compiled against.
-     * @hide
-     */
-    protected SQLiteDatabase mDatabase;
-
-    /** The SQL used to create this query */
-    /* package */ final String mSql;
-
-    /**
-     * Native linkage, do not modify. This comes from the database and should not be modified
-     * in here or in the native code.
-     * @hide
-     */
-    protected int nHandle;
-
-    /**
-     * the SQLiteCompiledSql object for the given sql statement.
-     */
-    /* package */ SQLiteCompiledSql mCompiledSql;
-
-    /**
-     * SQLiteCompiledSql statement id is populated with the corresponding object from the above
-     * member. This member is used by the native_bind_* methods
-     * @hide
-     */
-    protected int nStatement;
-
-    /**
-     * In the case of {@link SQLiteStatement}, this member stores the bindargs passed
-     * to the following methods, instead of actually doing the binding.
-     * <ul>
-     *   <li>{@link #bindBlob(int, byte[])}</li>
-     *   <li>{@link #bindDouble(int, double)}</li>
-     *   <li>{@link #bindLong(int, long)}</li>
-     *   <li>{@link #bindNull(int)}</li>
-     *   <li>{@link #bindString(int, String)}</li>
-     * </ul>
-     * <p>
-     * Each entry in the array is a Pair of
-     * <ol>
-     *   <li>bind arg position number</li>
-     *   <li>the value to be bound to the bindarg</li>
-     * </ol>
-     * <p>
-     * It is lazily initialized in the above bind methods
-     * and it is cleared in {@link #clearBindings()} method.
-     * <p>
-     * It is protected (in multi-threaded environment) by {@link SQLiteProgram}.this
-     */
-    /* package */ HashMap<Integer, Object> mBindArgs = null;
-    /* package */ final int mStatementType;
-    /* package */ static final int STATEMENT_CACHEABLE = 16;
-    /* package */ static final int STATEMENT_DONT_PREPARE = 32;
-    /* package */ static final int STATEMENT_USE_POOLED_CONN = 64;
-    /* package */ static final int STATEMENT_TYPE_MASK = 0x0f;
-
-    /* package */ SQLiteProgram(SQLiteDatabase db, String sql) {
-        this(db, sql, null, true);
-    }
-
-    /* package */ SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs,
-            boolean compileFlag) {
+    SQLiteProgram(SQLiteDatabase db, String sql, Object[] bindArgs) {
+        mDatabase = db;
         mSql = sql.trim();
+
         int n = DatabaseUtils.getSqlStatementType(mSql);
         switch (n) {
-            case DatabaseUtils.STATEMENT_UPDATE:
-                mStatementType = n | STATEMENT_CACHEABLE;
-                break;
-            case DatabaseUtils.STATEMENT_SELECT:
-                mStatementType = n | STATEMENT_CACHEABLE | STATEMENT_USE_POOLED_CONN;
-                break;
             case DatabaseUtils.STATEMENT_BEGIN:
             case DatabaseUtils.STATEMENT_COMMIT:
             case DatabaseUtils.STATEMENT_ABORT:
-                mStatementType = n | STATEMENT_DONT_PREPARE;
+                mReadOnly = false;
+                mColumnNames = EMPTY_STRING_ARRAY;
+                mNumParameters = 0;
                 break;
+
             default:
-                mStatementType = n;
-        }
-        db.acquireReference();
-        db.addSQLiteClosable(this);
-        mDatabase = db;
-        nHandle = db.mNativeHandle;
-        if (bindArgs != null) {
-            int size = bindArgs.length;
-            for (int i = 0; i < size; i++) {
-                this.addToBindArgs(i + 1, bindArgs[i]);
-            }
-        }
-        if (compileFlag) {
-            compileAndbindAllArgs();
-        }
-    }
-
-    private void compileSql() {
-        // only cache CRUD statements
-        if ((mStatementType & STATEMENT_CACHEABLE) == 0) {
-            mCompiledSql = new SQLiteCompiledSql(mDatabase, mSql);
-            nStatement = mCompiledSql.nStatement;
-            // since it is not in the cache, no need to acquire() it.
-            return;
+                boolean assumeReadOnly = (n == DatabaseUtils.STATEMENT_SELECT);
+                SQLiteStatementInfo info = new SQLiteStatementInfo();
+                db.getThreadSession().prepare(mSql,
+                        db.getThreadDefaultConnectionFlags(assumeReadOnly), info);
+                mReadOnly = info.readOnly;
+                mColumnNames = info.columnNames;
+                mNumParameters = info.numParameters;
+                break;
         }
 
-        mCompiledSql = mDatabase.getCompiledStatementForSql(mSql);
-        if (mCompiledSql == null) {
-            // create a new compiled-sql obj
-            mCompiledSql = new SQLiteCompiledSql(mDatabase, mSql);
-
-            // add it to the cache of compiled-sqls
-            // but before adding it and thus making it available for anyone else to use it,
-            // make sure it is acquired by me.
-            mCompiledSql.acquire();
-            mDatabase.addToCompiledQueries(mSql, mCompiledSql);
+        if (mNumParameters != 0) {
+            mBindArgs = new Object[mNumParameters];
         } else {
-            // it is already in compiled-sql cache.
-            // try to acquire the object.
-            if (!mCompiledSql.acquire()) {
-                int last = mCompiledSql.nStatement;
-                // the SQLiteCompiledSql in cache is in use by some other SQLiteProgram object.
-                // we can't have two different SQLiteProgam objects can't share the same
-                // CompiledSql object. create a new one.
-                // finalize it when I am done with it in "this" object.
-                mCompiledSql = new SQLiteCompiledSql(mDatabase, mSql);
-                // since it is not in the cache, no need to acquire() it.
+            mBindArgs = null;
+        }
+
+        if (bindArgs != null) {
+            if (bindArgs.length > mNumParameters) {
+                throw new IllegalArgumentException("Too many bind arguments.  "
+                        + bindArgs.length + " arguments were provided but the statement needs "
+                        + mNumParameters + " arguments.");
             }
+            System.arraycopy(bindArgs, 0, mBindArgs, 0, bindArgs.length);
         }
-        nStatement = mCompiledSql.nStatement;
     }
 
-    @Override
-    protected void onAllReferencesReleased() {
-        release();
-        mDatabase.removeSQLiteClosable(this);
-        mDatabase.releaseReference();
+    final SQLiteDatabase getDatabase() {
+        return mDatabase;
     }
 
-    @Override
-    protected void onAllReferencesReleasedFromContainer() {
-        release();
-        mDatabase.releaseReference();
-    }
-
-    /* package */ void release() {
-        if (mCompiledSql == null) {
-            return;
-        }
-        mDatabase.releaseCompiledSqlObj(mSql, mCompiledSql);
-        mCompiledSql = null;
-        nStatement = 0;
-    }
-
-    /**
-     * Returns a unique identifier for this program.
-     *
-     * @return a unique identifier for this program
-     * @deprecated do not use this method. it is not guaranteed to be the same across executions of
-     * the SQL statement contained in this object.
-     */
-    @Deprecated
-    public final int getUniqueId() {
-      return -1;
-    }
-
-    /**
-     * used only for testing purposes
-     */
-    /* package */ int getSqlStatementId() {
-      synchronized(this) {
-        return (mCompiledSql == null) ? 0 : nStatement;
-      }
-    }
-
-    /* package */ String getSqlString() {
+    final String getSql() {
         return mSql;
     }
 
-    private void bind(int type, int index, Object value) {
-        mDatabase.verifyDbIsOpen();
-        addToBindArgs(index, (type == Cursor.FIELD_TYPE_NULL) ? null : value);
-        if (nStatement > 0) {
-            // bind only if the SQL statement is compiled
-            acquireReference();
-            try {
-                switch (type) {
-                    case Cursor.FIELD_TYPE_NULL:
-                        native_bind_null(index);
-                        break;
-                    case Cursor.FIELD_TYPE_BLOB:
-                        native_bind_blob(index, (byte[]) value);
-                        break;
-                    case Cursor.FIELD_TYPE_FLOAT:
-                        native_bind_double(index, (Double) value);
-                        break;
-                    case Cursor.FIELD_TYPE_INTEGER:
-                        native_bind_long(index, (Long) value);
-                        break;
-                    case Cursor.FIELD_TYPE_STRING:
-                    default:
-                        native_bind_string(index, (String) value);
-                        break;
-                }
-            } finally {
-                releaseReference();
-            }
-        }
+    final Object[] getBindArgs() {
+        return mBindArgs;
+    }
+
+    final String[] getColumnNames() {
+        return mColumnNames;
+    }
+
+    /** @hide */
+    protected final SQLiteSession getSession() {
+        return mDatabase.getThreadSession();
+    }
+
+    /** @hide */
+    protected final int getConnectionFlags() {
+        return mDatabase.getThreadDefaultConnectionFlags(mReadOnly);
+    }
+
+    /** @hide */
+    protected final void onCorruption() {
+        mDatabase.onCorruption();
+    }
+
+    /**
+     * Unimplemented.
+     * @deprecated This method is deprecated and must not be used.
+     */
+    @Deprecated
+    public final int getUniqueId() {
+        return -1;
     }
 
     /**
@@ -245,7 +124,7 @@
      * @param index The 1-based index to the parameter to bind null to
      */
     public void bindNull(int index) {
-        bind(Cursor.FIELD_TYPE_NULL, index, null);
+        bind(index, null);
     }
 
     /**
@@ -256,7 +135,7 @@
      * @param value The value to bind
      */
     public void bindLong(int index, long value) {
-        bind(Cursor.FIELD_TYPE_INTEGER, index, value);
+        bind(index, value);
     }
 
     /**
@@ -267,7 +146,7 @@
      * @param value The value to bind
      */
     public void bindDouble(int index, double value) {
-        bind(Cursor.FIELD_TYPE_FLOAT, index, value);
+        bind(index, value);
     }
 
     /**
@@ -275,13 +154,13 @@
      * {@link #clearBindings} is called.
      *
      * @param index The 1-based index to the parameter to bind
-     * @param value The value to bind
+     * @param value The value to bind, must not be null
      */
     public void bindString(int index, String value) {
         if (value == null) {
             throw new IllegalArgumentException("the bind value at index " + index + " is null");
         }
-        bind(Cursor.FIELD_TYPE_STRING, index, value);
+        bind(index, value);
     }
 
     /**
@@ -289,29 +168,21 @@
      * {@link #clearBindings} is called.
      *
      * @param index The 1-based index to the parameter to bind
-     * @param value The value to bind
+     * @param value The value to bind, must not be null
      */
     public void bindBlob(int index, byte[] value) {
         if (value == null) {
             throw new IllegalArgumentException("the bind value at index " + index + " is null");
         }
-        bind(Cursor.FIELD_TYPE_BLOB, index, value);
+        bind(index, value);
     }
 
     /**
      * Clears all existing bindings. Unset bindings are treated as NULL.
      */
     public void clearBindings() {
-        mBindArgs = null;
-        if (this.nStatement == 0) {
-            return;
-        }
-        mDatabase.verifyDbIsOpen();
-        acquireReference();
-        try {
-            native_clear_bindings();
-        } finally {
-            releaseReference();
+        if (mBindArgs != null) {
+            Arrays.fill(mBindArgs, null);
         }
     }
 
@@ -319,102 +190,33 @@
      * Release this program's resources, making it invalid.
      */
     public void close() {
-        mBindArgs = null;
-        if (nHandle == 0 || !mDatabase.isOpen()) {
-            return;
-        }
         releaseReference();
     }
 
-    private void addToBindArgs(int index, Object value) {
-        if (mBindArgs == null) {
-            mBindArgs = new HashMap<Integer, Object>();
-        }
-        mBindArgs.put(index, value);
-    }
-
-    /* package */ void compileAndbindAllArgs() {
-        if ((mStatementType & STATEMENT_DONT_PREPARE) > 0) {
-            if (mBindArgs != null) {
-                throw new IllegalArgumentException("Can't pass bindargs for this sql :" + mSql);
-            }
-            // no need to prepare this SQL statement
-            return;
-        }
-        if (nStatement == 0) {
-            // SQL statement is not compiled yet. compile it now.
-            compileSql();
-        }
-        if (mBindArgs == null) {
-            return;
-        }
-        for (int index : mBindArgs.keySet()) {
-            Object value = mBindArgs.get(index);
-            if (value == null) {
-                native_bind_null(index);
-            } else if (value instanceof Double || value instanceof Float) {
-                native_bind_double(index, ((Number) value).doubleValue());
-            } else if (value instanceof Number) {
-                native_bind_long(index, ((Number) value).longValue());
-            } else if (value instanceof Boolean) {
-                Boolean bool = (Boolean)value;
-                native_bind_long(index, (bool) ? 1 : 0);
-                if (bool) {
-                    native_bind_long(index, 1);
-                } else {
-                    native_bind_long(index, 0);
-                }
-            } else if (value instanceof byte[]){
-                native_bind_blob(index, (byte[]) value);
-            } else {
-                native_bind_string(index, value.toString());
-            }
-        }
-    }
-
     /**
      * Given an array of String bindArgs, this method binds all of them in one single call.
      *
-     * @param bindArgs the String array of bind args.
+     * @param bindArgs the String array of bind args, none of which must be null.
      */
     public void bindAllArgsAsStrings(String[] bindArgs) {
-        if (bindArgs == null) {
-            return;
-        }
-        int size = bindArgs.length;
-        for (int i = 0; i < size; i++) {
-            bindString(i + 1, bindArgs[i]);
+        if (bindArgs != null) {
+            for (int i = bindArgs.length; i != 0; i--) {
+                bindString(i, bindArgs[i - 1]);
+            }
         }
     }
 
-    /* package */ synchronized final void setNativeHandle(int nHandle) {
-        this.nHandle = nHandle;
+    @Override
+    protected void onAllReferencesReleased() {
+        clearBindings();
     }
 
-    /**
-     * @hide
-     * Compiles SQL into a SQLite program.
-     *
-     * <P>The database lock must be held when calling this method.
-     * @param sql The SQL to compile.
-     */
-    protected final native void native_compile(String sql);
-
-    /**
-     * @hide
-     */
-    protected final native void native_finalize();
-
-    /** @hide */
-    protected final native void native_bind_null(int index);
-    /** @hide */
-    protected final native void native_bind_long(int index, long value);
-    /** @hide */
-    protected final native void native_bind_double(int index, double value);
-    /** @hide */
-    protected final native void native_bind_string(int index, String value);
-    /** @hide */
-    protected final native void native_bind_blob(int index, byte[] value);
-    private final native void native_clear_bindings();
+    private void bind(int index, Object value) {
+        if (index < 1 || index > mNumParameters) {
+            throw new IllegalArgumentException("Cannot bind argument at index "
+                    + index + " because the index is out of range.  "
+                    + "The statement has " + mNumParameters + " parameters.");
+        }
+        mBindArgs[index - 1] = value;
+    }
 }
-
diff --git a/core/java/android/database/sqlite/SQLiteQuery.java b/core/java/android/database/sqlite/SQLiteQuery.java
index 6dd2539..17aa886 100644
--- a/core/java/android/database/sqlite/SQLiteQuery.java
+++ b/core/java/android/database/sqlite/SQLiteQuery.java
@@ -17,60 +17,24 @@
 package android.database.sqlite;
 
 import android.database.CursorWindow;
-import android.os.SystemClock;
-import android.text.TextUtils;
 import android.util.Log;
 
 /**
- * A SQLite program that represents a query that reads the resulting rows into a CursorWindow.
- * This class is used by SQLiteCursor and isn't useful itself.
- *
- * SQLiteQuery is not internally synchronized so code using a SQLiteQuery from multiple
- * threads should perform its own synchronization when using the SQLiteQuery.
+ * Represents a query that reads the resulting rows into a {@link SQLiteQuery}.
+ * This class is used by {@link SQLiteCursor} and isn't useful itself.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
  */
 public final class SQLiteQuery extends SQLiteProgram {
     private static final String TAG = "SQLiteQuery";
 
-    private static native long nativeFillWindow(int databasePtr, int statementPtr, int windowPtr,
-            int offsetParam, int startPos, int requiredPos, boolean countAllRows);
-
-    private static native int nativeColumnCount(int statementPtr);
-    private static native String nativeColumnName(int statementPtr, int columnIndex);
-
-    /** The index of the unbound OFFSET parameter */
-    private int mOffsetIndex = 0;
-
-    private boolean mClosed = false;
-
-    /**
-     * Create a persistent query object.
-     *
-     * @param db The database that this query object is associated with
-     * @param query The SQL string for this query. 
-     * @param offsetIndex The 1-based index to the OFFSET parameter, 
-     */
-    /* package */ SQLiteQuery(SQLiteDatabase db, String query, int offsetIndex, String[] bindArgs) {
-        super(db, query);
-        mOffsetIndex = offsetIndex;
-        bindAllArgsAsStrings(bindArgs);
+    SQLiteQuery(SQLiteDatabase db, String query) {
+        super(db, query, null);
     }
 
     /**
-     * Constructor used to create new instance to replace a given instance of this class.
-     * This constructor is used when the current Query object is now associated with a different
-     * {@link SQLiteDatabase} object.
-     *
-     * @param db The database that this query object is associated with
-     * @param query the instance of {@link SQLiteQuery} to be replaced
-     */
-    /* package */ SQLiteQuery(SQLiteDatabase db, SQLiteQuery query) {
-        super(db, query.mSql);
-        this.mBindArgs = query.mBindArgs;
-        this.mOffsetIndex = query.mOffsetIndex;
-    }
-
-    /**
-     * Reads rows into a buffer. This method acquires the database lock.
+     * Reads rows into a buffer.
      *
      * @param window The window to fill into
      * @param startPos The start position for filling the window.
@@ -81,106 +45,30 @@
      * @return Number of rows that were enumerated.  Might not be all rows
      * unless countAllRows is true.
      */
-    /* package */ int fillWindow(CursorWindow window,
-            int startPos, int requiredPos, boolean countAllRows) {
-        mDatabase.lock(mSql);
-        long timeStart = SystemClock.uptimeMillis();
+    int fillWindow(CursorWindow window, int startPos, int requiredPos, boolean countAllRows) {
+        acquireReference();
         try {
-            acquireReference();
+            window.acquireReference();
             try {
-                window.acquireReference();
-                long result = nativeFillWindow(nHandle, nStatement, window.mWindowPtr,
-                        mOffsetIndex, startPos, requiredPos, countAllRows);
-                int actualPos = (int)(result >> 32);
-                int countedRows = (int)result;
-                window.setStartPosition(actualPos);
-                if (SQLiteDebug.DEBUG_LOG_SLOW_QUERIES) {
-                    long elapsed = SystemClock.uptimeMillis() - timeStart;
-                    if (SQLiteDebug.shouldLogSlowQuery(elapsed)) {
-                        Log.d(TAG, "fillWindow took " + elapsed
-                                + " ms: window=\"" + window
-                                + "\", startPos=" + startPos
-                                + ", requiredPos=" + requiredPos
-                                + ", offset=" + mOffsetIndex
-                                + ", actualPos=" + actualPos
-                                + ", filledRows=" + window.getNumRows()
-                                + ", countedRows=" + countedRows
-                                + ", query=\"" + mSql + "\""
-                                + ", args=[" + (mBindArgs != null ?
-                                        TextUtils.join(", ", mBindArgs.values()) : "")
-                                + "]");
-                    }
-                }
-                mDatabase.logTimeStat(mSql, timeStart);
-                return countedRows;
-            } catch (IllegalStateException e){
-                // simply ignore it
-                return 0;
-            } catch (SQLiteDatabaseCorruptException e) {
-                mDatabase.onCorruption();
-                throw e;
-            } catch (SQLiteException e) {
-                Log.e(TAG, "exception: " + e.getMessage() + "; query: " + mSql);
-                throw e;
+                int numRows = getSession().executeForCursorWindow(getSql(), getBindArgs(),
+                        window, startPos, requiredPos, countAllRows, getConnectionFlags());
+                return numRows;
+            } catch (SQLiteDatabaseCorruptException ex) {
+                onCorruption();
+                throw ex;
+            } catch (SQLiteException ex) {
+                Log.e(TAG, "exception: " + ex.getMessage() + "; query: " + getSql());
+                throw ex;
             } finally {
                 window.releaseReference();
             }
         } finally {
             releaseReference();
-            mDatabase.unlock();
-        }
-    }
-
-    /**
-     * Get the column count for the statement. Only valid on query based
-     * statements. The database must be locked
-     * when calling this method.
-     * 
-     * @return The number of column in the statement's result set.
-     */
-    /* package */ int columnCountLocked() {
-        acquireReference();
-        try {
-            return nativeColumnCount(nStatement);
-        } finally {
-            releaseReference();
-        }
-    }
-
-    /**
-     * Retrieves the column name for the given column index. The database must be locked
-     * when calling this method.
-     * 
-     * @param columnIndex the index of the column to get the name for
-     * @return The requested column's name
-     */
-    /* package */ String columnNameLocked(int columnIndex) {
-        acquireReference();
-        try {
-            return nativeColumnName(nStatement, columnIndex);
-        } finally {
-            releaseReference();
         }
     }
 
     @Override
     public String toString() {
-        return "SQLiteQuery: " + mSql;
-    }
-
-    @Override
-    public void close() {
-        super.close();
-        mClosed = true;
-    }
-
-    /**
-     * Called by SQLiteCursor when it is requeried.
-     */
-    /* package */ void requery() {
-        if (mClosed) {
-            throw new IllegalStateException("requerying a closed cursor");
-        }
-        compileAndbindAllArgs();
+        return "SQLiteQuery: " + getSql();
     }
 }
diff --git a/core/java/android/database/sqlite/SQLiteQueryBuilder.java b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
index 8f8eb6e..1b7b398 100644
--- a/core/java/android/database/sqlite/SQLiteQueryBuilder.java
+++ b/core/java/android/database/sqlite/SQLiteQueryBuilder.java
@@ -341,7 +341,7 @@
             // in both the wrapped and original forms.
             String sqlForValidation = buildQuery(projectionIn, "(" + selection + ")", groupBy,
                     having, sortOrder, limit);
-            validateSql(db, sqlForValidation); // will throw if query is invalid
+            validateQuerySql(db, sqlForValidation); // will throw if query is invalid
         }
 
         String sql = buildQuery(
@@ -357,16 +357,12 @@
     }
 
     /**
-     * Verifies that a SQL statement is valid by compiling it.
+     * Verifies that a SQL SELECT statement is valid by compiling it.
      * If the SQL statement is not valid, this method will throw a {@link SQLiteException}.
      */
-    private void validateSql(SQLiteDatabase db, String sql) {
-        db.lock(sql);
-        try {
-            new SQLiteCompiledSql(db, sql).releaseSqlStatement();
-        } finally {
-            db.unlock();
-        }
+    private void validateQuerySql(SQLiteDatabase db, String sql) {
+        db.getThreadSession().prepare(sql,
+                db.getThreadDefaultConnectionFlags(true /*readOnly*/), null);
     }
 
     /**
diff --git a/core/java/android/database/sqlite/SQLiteSession.java b/core/java/android/database/sqlite/SQLiteSession.java
new file mode 100644
index 0000000..61fe45a
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteSession.java
@@ -0,0 +1,878 @@
+/*
+ * 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 android.database.sqlite;
+
+import android.database.CursorWindow;
+import android.database.DatabaseUtils;
+import android.os.ParcelFileDescriptor;
+
+/**
+ * Provides a single client the ability to use a database.
+ *
+ * <h2>About database sessions</h2>
+ * <p>
+ * Database access is always performed using a session.  The session
+ * manages the lifecycle of transactions and database connections.
+ * </p><p>
+ * Sessions can be used to perform both read-only and read-write operations.
+ * There is some advantage to knowing when a session is being used for
+ * read-only purposes because the connection pool can optimize the use
+ * of the available connections to permit multiple read-only operations
+ * to execute in parallel whereas read-write operations may need to be serialized.
+ * </p><p>
+ * When <em>Write Ahead Logging (WAL)</em> is enabled, the database can
+ * execute simultaneous read-only and read-write transactions, provided that
+ * at most one read-write transaction is performed at a time.  When WAL is not
+ * enabled, read-only transactions can execute in parallel but read-write
+ * transactions are mutually exclusive.
+ * </p>
+ *
+ * <h2>Ownership and concurrency guarantees</h2>
+ * <p>
+ * Session objects are not thread-safe.  In fact, session objects are thread-bound.
+ * The {@link SQLiteDatabase} uses a thread-local variable to associate a session
+ * with each thread for the use of that thread alone.  Consequently, each thread
+ * has its own session object and therefore its own transaction state independent
+ * of other threads.
+ * </p><p>
+ * A thread has at most one session per database.  This constraint ensures that
+ * a thread can never use more than one database connection at a time for a
+ * given database.  As the number of available database connections is limited,
+ * if a single thread tried to acquire multiple connections for the same database
+ * at the same time, it might deadlock.  Therefore we allow there to be only
+ * one session (so, at most one connection) per thread per database.
+ * </p>
+ *
+ * <h2>Transactions</h2>
+ * <p>
+ * There are two kinds of transaction: implicit transactions and explicit
+ * transactions.
+ * </p><p>
+ * An implicit transaction is created whenever a database operation is requested
+ * and there is no explicit transaction currently in progress.  An implicit transaction
+ * only lasts for the duration of the database operation in question and then it
+ * is ended.  If the database operation was successful, then its changes are committed.
+ * </p><p>
+ * An explicit transaction is started by calling {@link #beginTransaction} and
+ * specifying the desired transaction mode.  Once an explicit transaction has begun,
+ * all subsequent database operations will be performed as part of that transaction.
+ * To end an explicit transaction, first call {@link #setTransactionSuccessful} if the
+ * transaction was successful, then call {@link #end}.  If the transaction was
+ * marked successful, its changes will be committed, otherwise they will be rolled back.
+ * </p><p>
+ * Explicit transactions can also be nested.  A nested explicit transaction is
+ * started with {@link #beginTransaction}, marked successful with
+ * {@link #setTransactionSuccessful}and ended with {@link #endTransaction}.
+ * If any nested transaction is not marked successful, then the entire transaction
+ * including all of its nested transactions will be rolled back
+ * when the outermost transaction is ended.
+ * </p><p>
+ * To improve concurrency, an explicit transaction can be yielded by calling
+ * {@link #yieldTransaction}.  If there is contention for use of the database,
+ * then yielding ends the current transaction, commits its changes, releases the
+ * database connection for use by another session for a little while, and starts a
+ * new transaction with the same properties as the original one.
+ * Changes committed by {@link #yieldTransaction} cannot be rolled back.
+ * </p><p>
+ * When a transaction is started, the client can provide a {@link SQLiteTransactionListener}
+ * to listen for notifications of transaction-related events.
+ * </p><p>
+ * Recommended usage:
+ * <code><pre>
+ * // First, begin the transaction.
+ * session.beginTransaction(SQLiteSession.TRANSACTION_MODE_DEFERRED, 0);
+ * try {
+ *     // Then do stuff...
+ *     session.execute("INSERT INTO ...", null, 0);
+ *
+ *     // As the very last step before ending the transaction, mark it successful.
+ *     session.setTransactionSuccessful();
+ * } finally {
+ *     // Finally, end the transaction.
+ *     // This statement will commit the transaction if it was marked successful or
+ *     // roll it back otherwise.
+ *     session.endTransaction();
+ * }
+ * </pre></code>
+ * </p>
+ *
+ * <h2>Database connections</h2>
+ * <p>
+ * A {@link SQLiteDatabase} can have multiple active sessions at the same
+ * time.  Each session acquires and releases connections to the database
+ * as needed to perform each requested database transaction.  If all connections
+ * are in use, then database transactions on some sessions will block until a
+ * connection becomes available.
+ * </p><p>
+ * The session acquires a single database connection only for the duration
+ * of a single (implicit or explicit) database transaction, then releases it.
+ * This characteristic allows a small pool of database connections to be shared
+ * efficiently by multiple sessions as long as they are not all trying to perform
+ * database transactions at the same time.
+ * </p>
+ *
+ * <h2>Responsiveness</h2>
+ * <p>
+ * Because there are a limited number of database connections and the session holds
+ * a database connection for the entire duration of a database transaction,
+ * it is important to keep transactions short.  This is especially important
+ * for read-write transactions since they may block other transactions
+ * from executing.  Consider calling {@link #yieldTransaction} periodically
+ * during long-running transactions.
+ * </p><p>
+ * Another important consideration is that transactions that take too long to
+ * run may cause the application UI to become unresponsive.  Even if the transaction
+ * is executed in a background thread, the user will get bored and
+ * frustrated if the application shows no data for several seconds while
+ * a transaction runs.
+ * </p><p>
+ * Guidelines:
+ * <ul>
+ * <li>Do not perform database transactions on the UI thread.</li>
+ * <li>Keep database transactions as short as possible.</li>
+ * <li>Simple queries often run faster than complex queries.</li>
+ * <li>Measure the performance of your database transactions.</li>
+ * <li>Consider what will happen when the size of the data set grows.
+ * A query that works well on 100 rows may struggle with 10,000.</li>
+ * </ul>
+ *
+ * TODO: Support timeouts on all possibly blocking operations.
+ *
+ * @hide
+ */
+public final class SQLiteSession {
+    private final SQLiteConnectionPool mConnectionPool;
+
+    private SQLiteConnection mConnection;
+    private int mConnectionFlags;
+    private Transaction mTransactionPool;
+    private Transaction mTransactionStack;
+
+    /**
+     * Transaction mode: Deferred.
+     * <p>
+     * In a deferred transaction, no locks are acquired on the database
+     * until the first operation is performed.  If the first operation is
+     * read-only, then a <code>SHARED</code> lock is acquired, otherwise
+     * a <code>RESERVED</code> lock is acquired.
+     * </p><p>
+     * While holding a <code>SHARED</code> lock, this session is only allowed to
+     * read but other sessions are allowed to read or write.
+     * While holding a <code>RESERVED</code> lock, this session is allowed to read
+     * or write but other sessions are only allowed to read.
+     * </p><p>
+     * Because the lock is only acquired when needed in a deferred transaction,
+     * it is possible for another session to write to the database first before
+     * this session has a chance to do anything.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN DEFERRED</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_DEFERRED = 0;
+
+    /**
+     * Transaction mode: Immediate.
+     * <p>
+     * When an immediate transaction begins, the session acquires a
+     * <code>RESERVED</code> lock.
+     * </p><p>
+     * While holding a <code>RESERVED</code> lock, this session is allowed to read
+     * or write but other sessions are only allowed to read.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN IMMEDIATE</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_IMMEDIATE = 1;
+
+    /**
+     * Transaction mode: Exclusive.
+     * <p>
+     * When an exclusive transaction begins, the session acquires an
+     * <code>EXCLUSIVE</code> lock.
+     * </p><p>
+     * While holding an <code>EXCLUSIVE</code> lock, this session is allowed to read
+     * or write but no other sessions are allowed to access the database.
+     * </p><p>
+     * Corresponds to the SQLite <code>BEGIN EXCLUSIVE</code> transaction mode.
+     * </p>
+     */
+    public static final int TRANSACTION_MODE_EXCLUSIVE = 2;
+
+    /**
+     * Creates a session bound to the specified connection pool.
+     *
+     * @param connectionPool The connection pool.
+     */
+    public SQLiteSession(SQLiteConnectionPool connectionPool) {
+        if (connectionPool == null) {
+            throw new IllegalArgumentException("connectionPool must not be null");
+        }
+
+        mConnectionPool = connectionPool;
+    }
+
+    /**
+     * Returns true if the session has a transaction in progress.
+     *
+     * @return True if the session has a transaction in progress.
+     */
+    public boolean hasTransaction() {
+        return mTransactionStack != null;
+    }
+
+    /**
+     * Returns true if the session has a nested transaction in progress.
+     *
+     * @return True if the session has a nested transaction in progress.
+     */
+    public boolean hasNestedTransaction() {
+        return mTransactionStack != null && mTransactionStack.mParent != null;
+    }
+
+    /**
+     * Returns true if the session has an active database connection.
+     *
+     * @return True if the session has an active database connection.
+     */
+    public boolean hasConnection() {
+        return mConnection != null;
+    }
+
+    /**
+     * Begins a transaction.
+     * <p>
+     * Transactions may nest.  If the transaction is not in progress,
+     * then a database connection is obtained and a new transaction is started.
+     * Otherwise, a nested transaction is started.
+     * </p><p>
+     * Each call to {@link #beginTransaction} must be matched exactly by a call
+     * to {@link #endTransaction}.  To mark a transaction as successful,
+     * call {@link #setTransactionSuccessful} before calling {@link #endTransaction}.
+     * If the transaction is not successful, or if any of its nested
+     * transactions were not successful, then the entire transaction will
+     * be rolled back when the outermost transaction is ended.
+     * </p>
+     *
+     * @param transactionMode The transaction mode.  One of: {@link #TRANSACTION_MODE_DEFERRED},
+     * {@link #TRANSACTION_MODE_IMMEDIATE}, or {@link #TRANSACTION_MODE_EXCLUSIVE}.
+     * Ignored when creating a nested transaction.
+     * @param transactionListener The transaction listener, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     *
+     * @throws IllegalStateException if {@link #setTransactionSuccessful} has already been
+     * called for the current transaction.
+     *
+     * @see #setTransactionSuccessful
+     * @see #yieldTransaction
+     * @see #endTransaction
+     */
+    public void beginTransaction(int transactionMode,
+            SQLiteTransactionListener transactionListener, int connectionFlags) {
+        throwIfTransactionMarkedSuccessful();
+        beginTransactionUnchecked(transactionMode, transactionListener, connectionFlags);
+    }
+
+    private void beginTransactionUnchecked(int transactionMode,
+            SQLiteTransactionListener transactionListener, int connectionFlags) {
+        acquireConnectionIfNoTransaction(null, connectionFlags); // might throw
+        try {
+            // Set up the transaction such that we can back out safely
+            // in case we fail part way.
+            if (mTransactionStack == null) {
+                // Execute SQL might throw a runtime exception.
+                switch (transactionMode) {
+                    case TRANSACTION_MODE_IMMEDIATE:
+                        mConnection.execute("BEGIN IMMEDIATE;", null); // might throw
+                        break;
+                    case TRANSACTION_MODE_EXCLUSIVE:
+                        mConnection.execute("BEGIN EXCLUSIVE;", null); // might throw
+                        break;
+                    default:
+                        mConnection.execute("BEGIN;", null); // might throw
+                        break;
+                }
+            }
+
+            // Listener might throw a runtime exception.
+            if (transactionListener != null) {
+                try {
+                    transactionListener.onBegin(); // might throw
+                } catch (RuntimeException ex) {
+                    if (mTransactionStack == null) {
+                        mConnection.execute("ROLLBACK;", null); // might throw
+                    }
+                    throw ex;
+                }
+            }
+
+            // Bookkeeping can't throw, except an OOM, which is just too bad...
+            Transaction transaction = obtainTransaction(transactionMode, transactionListener);
+            transaction.mParent = mTransactionStack;
+            mTransactionStack = transaction;
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Marks the current transaction as having completed successfully.
+     * <p>
+     * This method can be called at most once between {@link #beginTransaction} and
+     * {@link #endTransaction} to indicate that the changes made by the transaction should be
+     * committed.  If this method is not called, the changes will be rolled back
+     * when the transaction is ended.
+     * </p>
+     *
+     * @throws IllegalStateException if there is no current transaction, or if
+     * {@link #setTransactionSuccessful} has already been called for the current transaction.
+     *
+     * @see #beginTransaction
+     * @see #endTransaction
+     */
+    public void setTransactionSuccessful() {
+        throwIfNoTransaction();
+        throwIfTransactionMarkedSuccessful();
+
+        mTransactionStack.mMarkedSuccessful = true;
+    }
+
+    /**
+     * Ends the current transaction and commits or rolls back changes.
+     * <p>
+     * If this is the outermost transaction (not nested within any other
+     * transaction), then the changes are committed if {@link #setTransactionSuccessful}
+     * was called or rolled back otherwise.
+     * </p><p>
+     * This method must be called exactly once for each call to {@link #beginTransaction}.
+     * </p>
+     *
+     * @throws IllegalStateException if there is no current transaction.
+     *
+     * @see #beginTransaction
+     * @see #setTransactionSuccessful
+     * @see #yieldTransaction
+     */
+    public void endTransaction() {
+        throwIfNoTransaction();
+        assert mConnection != null;
+
+        endTransactionUnchecked();
+    }
+
+    private void endTransactionUnchecked() {
+        final Transaction top = mTransactionStack;
+        boolean successful = top.mMarkedSuccessful && !top.mChildFailed;
+
+        RuntimeException listenerException = null;
+        final SQLiteTransactionListener listener = top.mListener;
+        if (listener != null) {
+            try {
+                if (successful) {
+                    listener.onCommit(); // might throw
+                } else {
+                    listener.onRollback(); // might throw
+                }
+            } catch (RuntimeException ex) {
+                listenerException = ex;
+                successful = false;
+            }
+        }
+
+        mTransactionStack = top.mParent;
+        recycleTransaction(top);
+
+        if (mTransactionStack != null) {
+            if (!successful) {
+                mTransactionStack.mChildFailed = true;
+            }
+        } else {
+            try {
+                if (successful) {
+                    mConnection.execute("COMMIT;", null); // might throw
+                } else {
+                    mConnection.execute("ROLLBACK;", null); // might throw
+                }
+            } finally {
+                releaseConnectionIfNoTransaction(); // might throw
+            }
+        }
+
+        if (listenerException != null) {
+            throw listenerException;
+        }
+    }
+
+    /**
+     * Temporarily ends a transaction to let other threads have use of
+     * the database.  Begins a new transaction after a specified delay.
+     * <p>
+     * If there are other threads waiting to acquire connections,
+     * then the current transaction is committed and the database
+     * connection is released.  After a short delay, a new transaction
+     * is started.
+     * </p><p>
+     * The transaction is assumed to be successful so far.  Do not call
+     * {@link #setTransactionSuccessful()} before calling this method.
+     * This method will fail if the transaction has already been marked
+     * successful.
+     * </p><p>
+     * The changes that were committed by a yield cannot be rolled back later.
+     * </p><p>
+     * Before this method was called, there must already have been
+     * a transaction in progress.  When this method returns, there will
+     * still be a transaction in progress, either the same one as before
+     * or a new one if the transaction was actually yielded.
+     * </p><p>
+     * This method should not be called when there is a nested transaction
+     * in progress because it is not possible to yield a nested transaction.
+     * If <code>throwIfNested</code> is true, then attempting to yield
+     * a nested transaction will throw {@link IllegalStateException}, otherwise
+     * the method will return <code>false</code> in that case.
+     * </p><p>
+     * If there is no nested transaction in progress but a previous nested
+     * transaction failed, then the transaction is not yielded (because it
+     * must be rolled back) and this method returns <code>false</code>.
+     * </p>
+     *
+     * @param sleepAfterYieldDelayMillis A delay time to wait after yielding
+     * the database connection to allow other threads some time to run.
+     * If the value is less than or equal to zero, there will be no additional
+     * delay beyond the time it will take to begin a new transaction.
+     * @param throwIfUnsafe If true, then instead of returning false when no
+     * transaction is in progress, a nested transaction is in progress, or when
+     * the transaction has already been marked successful, throws {@link IllegalStateException}.
+     * @return True if the transaction was actually yielded.
+     *
+     * @throws IllegalStateException if <code>throwIfNested</code> is true and
+     * there is no current transaction, there is a nested transaction in progress or
+     * if {@link #setTransactionSuccessful} has already been called for the current transaction.
+     *
+     * @see #beginTransaction
+     * @see #endTransaction
+     */
+    public boolean yieldTransaction(long sleepAfterYieldDelayMillis, boolean throwIfUnsafe) {
+        if (throwIfUnsafe) {
+            throwIfNoTransaction();
+            throwIfTransactionMarkedSuccessful();
+            throwIfNestedTransaction();
+        } else {
+            if (mTransactionStack == null || mTransactionStack.mMarkedSuccessful
+                    || mTransactionStack.mParent != null) {
+                return false;
+            }
+        }
+        assert mConnection != null;
+
+        if (mTransactionStack.mChildFailed) {
+            return false;
+        }
+
+        return yieldTransactionUnchecked(sleepAfterYieldDelayMillis); // might throw
+    }
+
+    private boolean yieldTransactionUnchecked(long sleepAfterYieldDelayMillis) {
+        if (!mConnectionPool.shouldYieldConnection(mConnection, mConnectionFlags)) {
+            return false;
+        }
+
+        final int transactionMode = mTransactionStack.mMode;
+        final SQLiteTransactionListener listener = mTransactionStack.mListener;
+        final int connectionFlags = mConnectionFlags;
+        endTransactionUnchecked(); // might throw
+
+        if (sleepAfterYieldDelayMillis > 0) {
+            try {
+                Thread.sleep(sleepAfterYieldDelayMillis);
+            } catch (InterruptedException ex) {
+                // we have been interrupted, that's all we need to do
+            }
+        }
+
+        beginTransactionUnchecked(transactionMode, listener, connectionFlags); // might throw
+        return true;
+    }
+
+    /**
+     * Prepares a statement for execution but does not bind its parameters or execute it.
+     * <p>
+     * This method can be used to check for syntax errors during compilation
+     * prior to execution of the statement.  If the {@code outStatementInfo} argument
+     * is not null, the provided {@link SQLiteStatementInfo} object is populated
+     * with information about the statement.
+     * </p><p>
+     * A prepared statement makes no reference to the arguments that may eventually
+     * be bound to it, consequently it it possible to cache certain prepared statements
+     * such as SELECT or INSERT/UPDATE statements.  If the statement is cacheable,
+     * then it will be stored in the cache for later and reused if possible.
+     * </p>
+     *
+     * @param sql The SQL statement to prepare.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @param outStatementInfo The {@link SQLiteStatementInfo} object to populate
+     * with information about the statement, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error.
+     */
+    public void prepare(String sql, int connectionFlags, SQLiteStatementInfo outStatementInfo) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            mConnection.prepare(sql, outStatementInfo); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that does not return a result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public void execute(String sql, Object[] bindArgs, int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            mConnection.execute(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single <code>long</code> result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>long</code>, or zero if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public long executeForLong(String sql, Object[] bindArgs, int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return 0;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForLong(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single {@link String} result.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The value of the first column in the first row of the result set
+     * as a <code>String</code>, or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public String executeForString(String sql, Object[] bindArgs, int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return null;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForString(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a single BLOB result as a
+     * file descriptor to a shared memory region.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The file descriptor for a shared memory region that contains
+     * the value of the first column in the first row of the result set as a BLOB,
+     * or null if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public ParcelFileDescriptor executeForBlobFileDescriptor(String sql, Object[] bindArgs,
+            int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return null;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForBlobFileDescriptor(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns a count of the number of rows
+     * that were changed.  Use for UPDATE or DELETE SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The number of rows that were changed.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public int executeForChangedRowCount(String sql, Object[] bindArgs, int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return 0;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForChangedRowCount(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement that returns the row id of the last row inserted
+     * by the statement.  Use for INSERT SQL statements.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The row id of the last row that was inserted, or 0 if none.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public long executeForLastInsertedRowId(String sql, Object[] bindArgs, int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            return 0;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForLastInsertedRowId(sql, bindArgs); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Executes a statement and populates the specified {@link CursorWindow}
+     * with a range of results.  Returns the number of rows that were counted
+     * during query execution.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param window The cursor window to clear and fill.
+     * @param startPos The start position for filling the window.
+     * @param requiredPos The position of a row that MUST be in the window.
+     * If it won't fit, then the query should discard part of what it filled
+     * so that it does.  Must be greater than or equal to <code>startPos</code>.
+     * @param countAllRows True to count all rows that the query would return
+     * regagless of whether they fit in the window.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return The number of rows that were counted during query execution.  Might
+     * not be all rows in the result set unless <code>countAllRows</code> is true.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    public int executeForCursorWindow(String sql, Object[] bindArgs,
+            CursorWindow window, int startPos, int requiredPos, boolean countAllRows,
+            int connectionFlags) {
+        if (sql == null) {
+            throw new IllegalArgumentException("sql must not be null.");
+        }
+        if (window == null) {
+            throw new IllegalArgumentException("window must not be null.");
+        }
+
+        if (executeSpecial(sql, bindArgs, connectionFlags)) {
+            window.clear();
+            return 0;
+        }
+
+        acquireConnectionIfNoTransaction(sql, connectionFlags); // might throw
+        try {
+            return mConnection.executeForCursorWindow(sql, bindArgs,
+                    window, startPos, requiredPos, countAllRows); // might throw
+        } finally {
+            releaseConnectionIfNoTransaction(); // might throw
+        }
+    }
+
+    /**
+     * Performs special reinterpretation of certain SQL statements such as "BEGIN",
+     * "COMMIT" and "ROLLBACK" to ensure that transaction state invariants are
+     * maintained.
+     *
+     * This function is mainly used to support legacy apps that perform their
+     * own transactions by executing raw SQL rather than calling {@link #beginTransaction}
+     * and the like.
+     *
+     * @param sql The SQL statement to execute.
+     * @param bindArgs The arguments to bind, or null if none.
+     * @param connectionFlags The connection flags to use if a connection must be
+     * acquired by this operation.  Refer to {@link SQLiteConnectionPool}.
+     * @return True if the statement was of a special form that was handled here,
+     * false otherwise.
+     *
+     * @throws SQLiteException if an error occurs, such as a syntax error
+     * or invalid number of bind arguments.
+     */
+    private boolean executeSpecial(String sql, Object[] bindArgs, int connectionFlags) {
+        final int type = DatabaseUtils.getSqlStatementType(sql);
+        switch (type) {
+            case DatabaseUtils.STATEMENT_BEGIN:
+                beginTransaction(TRANSACTION_MODE_EXCLUSIVE, null, connectionFlags);
+                return true;
+
+            case DatabaseUtils.STATEMENT_COMMIT:
+                setTransactionSuccessful();
+                endTransaction();
+                return true;
+
+            case DatabaseUtils.STATEMENT_ABORT:
+                endTransaction();
+                return true;
+        }
+        return false;
+    }
+
+    private void acquireConnectionIfNoTransaction(String sql, int connectionFlags) {
+        if (mTransactionStack == null) {
+            assert mConnection == null;
+            mConnection = mConnectionPool.acquireConnection(sql, connectionFlags); // might throw
+            mConnectionFlags = connectionFlags;
+        }
+    }
+
+    private void releaseConnectionIfNoTransaction() {
+        if (mTransactionStack == null && mConnection != null) {
+            try {
+                mConnectionPool.releaseConnection(mConnection); // might throw
+            } finally {
+                mConnection = null;
+            }
+        }
+    }
+
+    private void throwIfNoTransaction() {
+        if (mTransactionStack == null) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "there is no current transaction.");
+        }
+    }
+
+    private void throwIfTransactionMarkedSuccessful() {
+        if (mTransactionStack != null && mTransactionStack.mMarkedSuccessful) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "the transaction has already been marked successful.  The only "
+                    + "thing you can do now is call endTransaction().");
+        }
+    }
+
+    private void throwIfNestedTransaction() {
+        if (mTransactionStack == null && mTransactionStack.mParent != null) {
+            throw new IllegalStateException("Cannot perform this operation because "
+                    + "a nested transaction is in progress.");
+        }
+    }
+
+    private Transaction obtainTransaction(int mode, SQLiteTransactionListener listener) {
+        Transaction transaction = mTransactionPool;
+        if (transaction != null) {
+            mTransactionPool = transaction.mParent;
+            transaction.mParent = null;
+            transaction.mMarkedSuccessful = false;
+            transaction.mChildFailed = false;
+        } else {
+            transaction = new Transaction();
+        }
+        transaction.mMode = mode;
+        transaction.mListener = listener;
+        return transaction;
+    }
+
+    private void recycleTransaction(Transaction transaction) {
+        transaction.mParent = mTransactionPool;
+        transaction.mListener = null;
+        mTransactionPool = transaction;
+    }
+
+    private static final class Transaction {
+        public Transaction mParent;
+        public int mMode;
+        public SQLiteTransactionListener mListener;
+        public boolean mMarkedSuccessful;
+        public boolean mChildFailed;
+    }
+}
diff --git a/core/java/android/database/sqlite/SQLiteStatement.java b/core/java/android/database/sqlite/SQLiteStatement.java
index c99a6fb..4e20da0 100644
--- a/core/java/android/database/sqlite/SQLiteStatement.java
+++ b/core/java/android/database/sqlite/SQLiteStatement.java
@@ -16,47 +16,19 @@
 
 package android.database.sqlite;
 
-import android.database.DatabaseUtils;
 import android.os.ParcelFileDescriptor;
-import android.os.SystemClock;
-import android.util.Log;
-
-import java.io.IOException;
-
-import dalvik.system.BlockGuard;
 
 /**
- * A pre-compiled statement against a {@link SQLiteDatabase} that can be reused.
- * The statement cannot return multiple rows, but 1x1 result sets are allowed.
- * Don't use SQLiteStatement constructor directly, please use
- * {@link SQLiteDatabase#compileStatement(String)}
- *<p>
- * SQLiteStatement is NOT internally synchronized so code using a SQLiteStatement from multiple
- * threads should perform its own synchronization when using the SQLiteStatement.
+ * Represents a statement that can be executed against a database.  The statement
+ * cannot return multiple rows or columns, but single value (1 x 1) result sets
+ * are supported.
+ * <p>
+ * This class is not thread-safe.
+ * </p>
  */
-@SuppressWarnings("deprecation")
-public final class SQLiteStatement extends SQLiteProgram
-{
-    private static final String TAG = "SQLiteStatement";
-
-    private static final boolean READ = true;
-    private static final boolean WRITE = false;
-
-    private SQLiteDatabase mOrigDb;
-    private int mState;
-    /** possible value for {@link #mState}. indicates that a transaction is started. */
-    private static final int TRANS_STARTED = 1;
-    /** possible value for {@link #mState}. indicates that a lock is acquired. */
-    private static final int LOCK_ACQUIRED = 2;
-
-    /**
-     * Don't use SQLiteStatement constructor directly, please use
-     * {@link SQLiteDatabase#compileStatement(String)}
-     * @param db
-     * @param sql
-     */
-    /* package */ SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
-        super(db, sql, bindArgs, false /* don't compile sql statement */);
+public final class SQLiteStatement extends SQLiteProgram {
+    SQLiteStatement(SQLiteDatabase db, String sql, Object[] bindArgs) {
+        super(db, sql, bindArgs);
     }
 
     /**
@@ -67,7 +39,15 @@
      *         some reason
      */
     public void execute() {
-        executeUpdateDelete();
+        acquireReference();
+        try {
+            getSession().execute(getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
     }
 
     /**
@@ -79,21 +59,15 @@
      *         some reason
      */
     public int executeUpdateDelete() {
+        acquireReference();
         try {
-            saveSqlAsLastSqlStatement();
-            acquireAndLock(WRITE);
-            int numChanges = 0;
-            if ((mStatementType & STATEMENT_DONT_PREPARE) > 0) {
-                // since the statement doesn't have to be prepared,
-                // call the following native method which will not prepare
-                // the query plan
-                native_executeSql(mSql);
-            } else {
-                numChanges = native_execute();
-            }
-            return numChanges;
+            return getSession().executeForChangedRowCount(
+                    getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
         } finally {
-            releaseAndUnlock();
+            releaseReference();
         }
     }
 
@@ -107,23 +81,18 @@
      *         some reason
      */
     public long executeInsert() {
+        acquireReference();
         try {
-            saveSqlAsLastSqlStatement();
-            acquireAndLock(WRITE);
-            return native_executeInsert();
+            return getSession().executeForLastInsertedRowId(
+                    getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
         } finally {
-            releaseAndUnlock();
+            releaseReference();
         }
     }
 
-    private void saveSqlAsLastSqlStatement() {
-        if (((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
-                DatabaseUtils.STATEMENT_UPDATE) ||
-                (mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
-                DatabaseUtils.STATEMENT_BEGIN) {
-            mDatabase.setLastSqlStatement(mSql);
-        }
-    }
     /**
      * Execute a statement that returns a 1 by 1 table with a numeric value.
      * For example, SELECT COUNT(*) FROM table;
@@ -133,17 +102,15 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public long simpleQueryForLong() {
+        acquireReference();
         try {
-            long timeStart = acquireAndLock(READ);
-            long retValue = native_1x1_long();
-            mDatabase.logTimeStat(mSql, timeStart);
-            return retValue;
-        } catch (SQLiteDoneException e) {
-            throw new SQLiteDoneException(
-                    "expected 1 row from this query but query returned no data. check the query: " +
-                    mSql);
+            return getSession().executeForLong(
+                    getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
         } finally {
-            releaseAndUnlock();
+            releaseReference();
         }
     }
 
@@ -156,17 +123,15 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public String simpleQueryForString() {
+        acquireReference();
         try {
-            long timeStart = acquireAndLock(READ);
-            String retValue = native_1x1_string();
-            mDatabase.logTimeStat(mSql, timeStart);
-            return retValue;
-        } catch (SQLiteDoneException e) {
-            throw new SQLiteDoneException(
-                    "expected 1 row from this query but query returned no data. check the query: " +
-                    mSql);
+            return getSession().executeForString(
+                    getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
         } finally {
-            releaseAndUnlock();
+            releaseReference();
         }
     }
 
@@ -179,121 +144,20 @@
      * @throws android.database.sqlite.SQLiteDoneException if the query returns zero rows
      */
     public ParcelFileDescriptor simpleQueryForBlobFileDescriptor() {
-        try {
-            long timeStart = acquireAndLock(READ);
-            ParcelFileDescriptor retValue = native_1x1_blob_ashmem();
-            mDatabase.logTimeStat(mSql, timeStart);
-            return retValue;
-        } catch (IOException ex) {
-            Log.e(TAG, "simpleQueryForBlobFileDescriptor() failed", ex);
-            return null;
-        } catch (SQLiteDoneException e) {
-            throw new SQLiteDoneException(
-                    "expected 1 row from this query but query returned no data. check the query: " +
-                    mSql);
-        } finally {
-            releaseAndUnlock();
-        }
-    }
-
-    /**
-     * Called before every method in this class before executing a SQL statement,
-     * this method does the following:
-     * <ul>
-     *   <li>make sure the database is open</li>
-     *   <li>get a database connection from the connection pool,if possible</li>
-     *   <li>notifies {@link BlockGuard} of read/write</li>
-     *   <li>if the SQL statement is an update, start transaction if not already in one.
-     *   otherwise, get lock on the database</li>
-     *   <li>acquire reference on this object</li>
-     *   <li>and then return the current time _after_ the database lock was acquired</li>
-     * </ul>
-     * <p>
-     * This method removes the duplicate code from the other public
-     * methods in this class.
-     */
-    private long acquireAndLock(boolean rwFlag) {
-        mState = 0;
-        // use pooled database connection handles for SELECT SQL statements
-        mDatabase.verifyDbIsOpen();
-        SQLiteDatabase db = ((mStatementType & SQLiteProgram.STATEMENT_USE_POOLED_CONN) > 0)
-                ? mDatabase.getDbConnection(mSql) : mDatabase;
-        // use the database connection obtained above
-        mOrigDb = mDatabase;
-        mDatabase = db;
-        setNativeHandle(mDatabase.mNativeHandle);
-        if (rwFlag == WRITE) {
-            BlockGuard.getThreadPolicy().onWriteToDisk();
-        } else {
-            BlockGuard.getThreadPolicy().onReadFromDisk();
-        }
-
-        /*
-         * Special case handling of SQLiteDatabase.execSQL("BEGIN transaction").
-         * we know it is execSQL("BEGIN transaction") from the caller IF there is no lock held.
-         * beginTransaction() methods in SQLiteDatabase call lockForced() before
-         * calling execSQL("BEGIN transaction").
-         */
-        if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) == DatabaseUtils.STATEMENT_BEGIN) {
-            if (!mDatabase.isDbLockedByCurrentThread()) {
-                // transaction is  NOT started by calling beginTransaction() methods in
-                // SQLiteDatabase
-                mDatabase.setTransactionUsingExecSqlFlag();
-            }
-        } else if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
-                DatabaseUtils.STATEMENT_UPDATE) {
-            // got update SQL statement. if there is NO pending transaction, start one
-            if (!mDatabase.inTransaction()) {
-                mDatabase.beginTransactionNonExclusive();
-                mState = TRANS_STARTED;
-            }
-        }
-        // do I have database lock? if not, grab it.
-        if (!mDatabase.isDbLockedByCurrentThread()) {
-            mDatabase.lock(mSql);
-            mState = LOCK_ACQUIRED;
-        }
-
         acquireReference();
-        long startTime = SystemClock.uptimeMillis();
-        mDatabase.closePendingStatements();
-        compileAndbindAllArgs();
-        return startTime;
+        try {
+            return getSession().executeForBlobFileDescriptor(
+                    getSql(), getBindArgs(), getConnectionFlags());
+        } catch (SQLiteDatabaseCorruptException ex) {
+            onCorruption();
+            throw ex;
+        } finally {
+            releaseReference();
+        }
     }
 
-    /**
-     * this method releases locks and references acquired in {@link #acquireAndLock(boolean)}
-     */
-    private void releaseAndUnlock() {
-        releaseReference();
-        if (mState == TRANS_STARTED) {
-            try {
-                mDatabase.setTransactionSuccessful();
-            } finally {
-                mDatabase.endTransaction();
-            }
-        } else if (mState == LOCK_ACQUIRED) {
-            mDatabase.unlock();
-        }
-        if ((mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
-                DatabaseUtils.STATEMENT_COMMIT ||
-                (mStatementType & SQLiteProgram.STATEMENT_TYPE_MASK) ==
-                DatabaseUtils.STATEMENT_ABORT) {
-            mDatabase.resetTransactionUsingExecSqlFlag();
-        }
-        clearBindings();
-        // release the compiled sql statement so that the caller's SQLiteStatement no longer
-        // has a hard reference to a database object that may get deallocated at any point.
-        release();
-        // restore the database connection handle to the original value
-        mDatabase = mOrigDb;
-        setNativeHandle(mDatabase.mNativeHandle);
+    @Override
+    public String toString() {
+        return "SQLiteProgram: " + getSql();
     }
-
-    private final native int native_execute();
-    private final native long native_executeInsert();
-    private final native long native_1x1_long();
-    private final native String native_1x1_string();
-    private final native ParcelFileDescriptor native_1x1_blob_ashmem() throws IOException;
-    private final native void native_executeSql(String sql);
 }
diff --git a/core/java/android/database/sqlite/SQLiteStatementInfo.java b/core/java/android/database/sqlite/SQLiteStatementInfo.java
new file mode 100644
index 0000000..3edfdb0
--- /dev/null
+++ b/core/java/android/database/sqlite/SQLiteStatementInfo.java
@@ -0,0 +1,39 @@
+/*
+ * 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 android.database.sqlite;
+
+/**
+ * Describes a SQLite statement.
+ *
+ * @hide
+ */
+public final class SQLiteStatementInfo {
+    /**
+     * The number of parameters that the statement has.
+     */
+    public int numParameters;
+
+    /**
+     * The names of all columns in the result set of the statement.
+     */
+    public String[] columnNames;
+
+    /**
+     * True if the statement is read-only.
+     */
+    public boolean readOnly;
+}
diff --git a/core/java/android/server/BluetoothAdapterStateMachine.java b/core/java/android/server/BluetoothAdapterStateMachine.java
index ed59b03..7711caa 100644
--- a/core/java/android/server/BluetoothAdapterStateMachine.java
+++ b/core/java/android/server/BluetoothAdapterStateMachine.java
@@ -539,7 +539,7 @@
                     }
 
                     // we turn all the way to PowerOff with AIRPLANE_MODE_ON
-                    if (message.what == AIRPLANE_MODE_ON) {
+                    if (message.what == AIRPLANE_MODE_ON || mBluetoothService.isAirplaneModeOn()) {
                         // We inform all the per process callbacks
                         allProcessesCallback(false);
                         deferMessage(obtainMessage(AIRPLANE_MODE_ON));
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 94fbbc8..fecc8f9 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -1706,7 +1706,7 @@
     }
 
     /* Returns true if airplane mode is currently on */
-    private final boolean isAirplaneModeOn() {
+    /*package*/ final boolean isAirplaneModeOn() {
         return Settings.System.getInt(mContext.getContentResolver(),
                 Settings.System.AIRPLANE_MODE_ON, 0) == 1;
     }
diff --git a/core/java/android/util/LruCache.java b/core/java/android/util/LruCache.java
index f1014a7..51e373c 100644
--- a/core/java/android/util/LruCache.java
+++ b/core/java/android/util/LruCache.java
@@ -86,6 +86,23 @@
     }
 
     /**
+     * Sets the size of the cache.
+     * @param maxSize The new maximum size.
+     *
+     * @hide
+     */
+    public void resize(int maxSize) {
+        if (maxSize <= 0) {
+            throw new IllegalArgumentException("maxSize <= 0");
+        }
+
+        synchronized (this) {
+            this.maxSize = maxSize;
+        }
+        trimToSize(maxSize);
+    }
+
+    /**
      * Returns the value for {@code key} if it exists in the cache or can be
      * created by {@code #create}. If a value was returned, it is moved to the
      * head of the queue. This returns null if a value is not cached and cannot
diff --git a/core/jni/Android.mk b/core/jni/Android.mk
index 8be1996..39b84bb 100644
--- a/core/jni/Android.mk
+++ b/core/jni/Android.mk
@@ -39,12 +39,10 @@
 	android_opengl_GLES11Ext.cpp \
 	android_opengl_GLES20.cpp \
 	android_database_CursorWindow.cpp \
-	android_database_SQLiteCompiledSql.cpp \
+	android_database_SQLiteCommon.cpp \
+	android_database_SQLiteConnection.cpp \
+	android_database_SQLiteGlobal.cpp \
 	android_database_SQLiteDebug.cpp \
-	android_database_SQLiteDatabase.cpp \
-	android_database_SQLiteProgram.cpp \
-	android_database_SQLiteQuery.cpp \
-	android_database_SQLiteStatement.cpp \
 	android_emoji_EmojiFactory.cpp \
 	android_view_Display.cpp \
 	android_view_DisplayEventReceiver.cpp \
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index c006615..8a3063f 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -121,12 +121,9 @@
 extern int register_android_view_Surface(JNIEnv* env);
 extern int register_android_view_TextureView(JNIEnv* env);
 extern int register_android_database_CursorWindow(JNIEnv* env);
-extern int register_android_database_SQLiteCompiledSql(JNIEnv* env);
-extern int register_android_database_SQLiteDatabase(JNIEnv* env);
+extern int register_android_database_SQLiteConnection(JNIEnv* env);
+extern int register_android_database_SQLiteGlobal(JNIEnv* env);
 extern int register_android_database_SQLiteDebug(JNIEnv* env);
-extern int register_android_database_SQLiteProgram(JNIEnv* env);
-extern int register_android_database_SQLiteQuery(JNIEnv* env);
-extern int register_android_database_SQLiteStatement(JNIEnv* env);
 extern int register_android_debug_JNITest(JNIEnv* env);
 extern int register_android_nio_utils(JNIEnv* env);
 extern int register_android_text_format_Time(JNIEnv* env);
@@ -1141,12 +1138,9 @@
     REG_JNI(register_android_graphics_YuvImage),
 
     REG_JNI(register_android_database_CursorWindow),
-    REG_JNI(register_android_database_SQLiteCompiledSql),
-    REG_JNI(register_android_database_SQLiteDatabase),
+    REG_JNI(register_android_database_SQLiteConnection),
+    REG_JNI(register_android_database_SQLiteGlobal),
     REG_JNI(register_android_database_SQLiteDebug),
-    REG_JNI(register_android_database_SQLiteProgram),
-    REG_JNI(register_android_database_SQLiteQuery),
-    REG_JNI(register_android_database_SQLiteStatement),
     REG_JNI(register_android_os_Debug),
     REG_JNI(register_android_os_FileObserver),
     REG_JNI(register_android_os_FileUtils),
diff --git a/core/jni/android_database_CursorWindow.cpp b/core/jni/android_database_CursorWindow.cpp
index f927064..d53644d 100644
--- a/core/jni/android_database_CursorWindow.cpp
+++ b/core/jni/android_database_CursorWindow.cpp
@@ -31,8 +31,8 @@
 #include <unistd.h>
 
 #include "binder/CursorWindow.h"
-#include "sqlite3_exception.h"
 #include "android_util_Binder.h"
+#include "android_database_SQLiteCommon.h"
 
 namespace android {
 
@@ -59,14 +59,9 @@
 
 static jint nativeCreate(JNIEnv* env, jclass clazz, jstring nameObj, jint cursorWindowSize) {
     String8 name;
-    if (nameObj) {
-        const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
-        name.setTo(nameStr);
-        env->ReleaseStringUTFChars(nameObj, nameStr);
-    }
-    if (name.size() == 0) {
-        name.setTo("<unnamed>");
-    }
+    const char* nameStr = env->GetStringUTFChars(nameObj, NULL);
+    name.setTo(nameStr);
+    env->ReleaseStringUTFChars(nameObj, nameStr);
 
     CursorWindow* window;
     status_t status = CursorWindow::create(name, cursorWindowSize, &window);
diff --git a/core/jni/android_database_SQLiteCommon.cpp b/core/jni/android_database_SQLiteCommon.cpp
new file mode 100644
index 0000000..d5fdb15
--- /dev/null
+++ b/core/jni/android_database_SQLiteCommon.cpp
@@ -0,0 +1,139 @@
+/*
+ * 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.
+ */
+
+#include "android_database_SQLiteCommon.h"
+
+namespace android {
+
+/* throw a SQLiteException with a message appropriate for the error in handle */
+void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) {
+    throw_sqlite3_exception(env, handle, NULL);
+}
+
+/* throw a SQLiteException with the given message */
+void throw_sqlite3_exception(JNIEnv* env, const char* message) {
+    throw_sqlite3_exception(env, NULL, message);
+}
+
+/* throw a SQLiteException with a message appropriate for the error in handle
+   concatenated with the given message
+ */
+void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) {
+    if (handle) {
+        throw_sqlite3_exception(env, sqlite3_errcode(handle),
+                                sqlite3_errmsg(handle), message);
+    } else {
+        // we use SQLITE_OK so that a generic SQLiteException is thrown;
+        // any code not specified in the switch statement below would do.
+        throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message);
+    }
+}
+
+/* throw a SQLiteException for a given error code */
+void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) {
+    if (errcode == SQLITE_DONE) {
+        throw_sqlite3_exception(env, errcode, NULL, message);
+    } else {
+        char temp[21];
+        sprintf(temp, "error code %d", errcode);
+        throw_sqlite3_exception(env, errcode, temp, message);
+    }
+}
+
+/* throw a SQLiteException for a given error code, sqlite3message, and
+   user message
+ */
+void throw_sqlite3_exception(JNIEnv* env, int errcode,
+                             const char* sqlite3Message, const char* message) {
+    const char* exceptionClass;
+    switch (errcode) {
+        case SQLITE_IOERR:
+            exceptionClass = "android/database/sqlite/SQLiteDiskIOException";
+            break;
+        case SQLITE_CORRUPT:
+        case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also
+            exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException";
+            break;
+        case SQLITE_CONSTRAINT:
+           exceptionClass = "android/database/sqlite/SQLiteConstraintException";
+           break;
+        case SQLITE_ABORT:
+           exceptionClass = "android/database/sqlite/SQLiteAbortException";
+           break;
+        case SQLITE_DONE:
+           exceptionClass = "android/database/sqlite/SQLiteDoneException";
+           break;
+        case SQLITE_FULL:
+           exceptionClass = "android/database/sqlite/SQLiteFullException";
+           break;
+        case SQLITE_MISUSE:
+           exceptionClass = "android/database/sqlite/SQLiteMisuseException";
+           break;
+        case SQLITE_PERM:
+           exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
+           break;
+        case SQLITE_BUSY:
+           exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
+           break;
+        case SQLITE_LOCKED:
+           exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
+           break;
+        case SQLITE_READONLY:
+           exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
+           break;
+        case SQLITE_CANTOPEN:
+           exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
+           break;
+        case SQLITE_TOOBIG:
+           exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
+           break;
+        case SQLITE_RANGE:
+           exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
+           break;
+        case SQLITE_NOMEM:
+           exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
+           break;
+        case SQLITE_MISMATCH:
+           exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
+           break;
+        case SQLITE_UNCLOSED:
+           exceptionClass = "android/database/sqlite/SQLiteUnfinalizedObjectsException";
+           break;
+        default:
+           exceptionClass = "android/database/sqlite/SQLiteException";
+           break;
+    }
+
+    if (sqlite3Message != NULL && message != NULL) {
+        char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3);
+        if (fullMessage != NULL) {
+            strcpy(fullMessage, sqlite3Message);
+            strcat(fullMessage, ": ");
+            strcat(fullMessage, message);
+            jniThrowException(env, exceptionClass, fullMessage);
+            free(fullMessage);
+        } else {
+            jniThrowException(env, exceptionClass, sqlite3Message);
+        }
+    } else if (sqlite3Message != NULL) {
+        jniThrowException(env, exceptionClass, sqlite3Message);
+    } else {
+        jniThrowException(env, exceptionClass, message);
+    }
+}
+
+
+} // namespace android
diff --git a/core/jni/android_database_SQLiteCommon.h b/core/jni/android_database_SQLiteCommon.h
new file mode 100644
index 0000000..0cac176
--- /dev/null
+++ b/core/jni/android_database_SQLiteCommon.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2007 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.
+ */
+
+#ifndef _ANDROID_DATABASE_SQLITE_COMMON_H
+#define _ANDROID_DATABASE_SQLITE_COMMON_H
+
+#include <jni.h>
+#include <JNIHelp.h>
+
+#include <sqlite3.h>
+
+// Special log tags defined in SQLiteDebug.java.
+#define SQLITE_LOG_TAG "SQLiteLog"
+#define SQLITE_TRACE_TAG "SQLiteStatements"
+#define SQLITE_PROFILE_TAG "SQLiteTime"
+
+namespace android {
+
+/* throw a SQLiteException with a message appropriate for the error in handle */
+void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle);
+
+/* throw a SQLiteException with the given message */
+void throw_sqlite3_exception(JNIEnv* env, const char* message);
+
+/* throw a SQLiteException with a message appropriate for the error in handle
+   concatenated with the given message
+ */
+void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message);
+
+/* throw a SQLiteException for a given error code */
+void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message);
+
+void throw_sqlite3_exception(JNIEnv* env, int errcode,
+        const char* sqlite3Message, const char* message);
+
+}
+
+#endif // _ANDROID_DATABASE_SQLITE_COMMON_H
diff --git a/core/jni/android_database_SQLiteCompiledSql.cpp b/core/jni/android_database_SQLiteCompiledSql.cpp
deleted file mode 100644
index 857267a..0000000
--- a/core/jni/android_database_SQLiteCompiledSql.cpp
+++ /dev/null
@@ -1,123 +0,0 @@
-/*
- * Copyright (C) 2006-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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "Cursor"
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sqlite3_exception.h"
-
-
-namespace android {
-
-static jfieldID gHandleField;
-static jfieldID gStatementField;
-
-
-#define GET_STATEMENT(env, object) \
-        (sqlite3_stmt *)env->GetIntField(object, gStatementField)
-#define GET_HANDLE(env, object) \
-        (sqlite3 *)env->GetIntField(object, gHandleField)
-
-
-sqlite3_stmt * compile(JNIEnv* env, jobject object,
-                       sqlite3 * handle, jstring sqlString)
-{
-    int err;
-    jchar const * sql;
-    jsize sqlLen;
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-
-    // Make sure not to leak the statement if it already exists
-    if (statement != NULL) {
-        sqlite3_finalize(statement);
-        env->SetIntField(object, gStatementField, 0);
-    }
-
-    // Compile the SQL
-    sql = env->GetStringChars(sqlString, NULL);
-    sqlLen = env->GetStringLength(sqlString);
-    err = sqlite3_prepare16_v2(handle, sql, sqlLen * 2, &statement, NULL);
-    env->ReleaseStringChars(sqlString, sql);
-
-    if (err == SQLITE_OK) {
-        // Store the statement in the Java object for future calls
-        ALOGV("Prepared statement %p on %p", statement, handle);
-        env->SetIntField(object, gStatementField, (int)statement);
-        return statement;
-    } else {
-        // Error messages like 'near ")": syntax error' are not
-        // always helpful enough, so construct an error string that
-        // includes the query itself.
-        const char *query = env->GetStringUTFChars(sqlString, NULL);
-        char *message = (char*) malloc(strlen(query) + 50);
-        if (message) {
-            strcpy(message, ", while compiling: "); // less than 50 chars
-            strcat(message, query);
-        }
-        env->ReleaseStringUTFChars(sqlString, query);
-        throw_sqlite3_exception(env, handle, message);
-        free(message);
-        return NULL;
-    }
-}
-
-static void native_compile(JNIEnv* env, jobject object, jstring sqlString)
-{
-    compile(env, object, GET_HANDLE(env, object), sqlString);
-}
-
-
-static JNINativeMethod sMethods[] =
-{
-     /* name, signature, funcPtr */
-    {"native_compile", "(Ljava/lang/String;)V", (void *)native_compile},
-};
-
-int register_android_database_SQLiteCompiledSql(JNIEnv * env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/database/sqlite/SQLiteCompiledSql");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/database/sqlite/SQLiteCompiledSql");
-        return -1;
-    }
-
-    gHandleField = env->GetFieldID(clazz, "nHandle", "I");
-    gStatementField = env->GetFieldID(clazz, "nStatement", "I");
-
-    if (gHandleField == NULL || gStatementField == NULL) {
-        ALOGE("Error locating fields");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env,
-        "android/database/sqlite/SQLiteCompiledSql", sMethods, NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/core/jni/android_database_SQLiteConnection.cpp b/core/jni/android_database_SQLiteConnection.cpp
new file mode 100644
index 0000000..d0d53f6
--- /dev/null
+++ b/core/jni/android_database_SQLiteConnection.cpp
@@ -0,0 +1,959 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SQLiteConnection"
+
+#include <jni.h>
+#include <JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <utils/Log.h>
+#include <utils/String8.h>
+#include <utils/String16.h>
+#include <cutils/ashmem.h>
+#include <sys/mman.h>
+
+#include <string.h>
+#include <unistd.h>
+
+#include "binder/CursorWindow.h"
+
+#include <sqlite3.h>
+#include <sqlite3_android.h>
+
+#include "android_database_SQLiteCommon.h"
+
+#define UTF16_STORAGE 0
+#define ANDROID_TABLE "android_metadata"
+
+namespace android {
+
+static struct {
+    jfieldID name;
+    jfieldID numArgs;
+    jmethodID dispatchCallback;
+} gSQLiteCustomFunctionClassInfo;
+
+static struct {
+    jclass clazz;
+} gStringClassInfo;
+
+struct SQLiteConnection {
+    // Open flags.
+    // Must be kept in sync with the constants defined in SQLiteDatabase.java.
+    enum {
+        OPEN_READWRITE          = 0x00000000,
+        OPEN_READONLY           = 0x00000001,
+        OPEN_READ_MASK          = 0x00000001,
+        NO_LOCALIZED_COLLATORS  = 0x00000010,
+        CREATE_IF_NECESSARY     = 0x10000000,
+    };
+
+    sqlite3* const db;
+    const int openFlags;
+    const String8 path;
+    const String8 label;
+
+    SQLiteConnection(sqlite3* db, int openFlags, const String8& path, const String8& label) :
+        db(db), openFlags(openFlags), path(path), label(label) { }
+};
+
+// Called each time a statement begins execution, when tracing is enabled.
+static void sqliteTraceCallback(void *data, const char *sql) {
+    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
+    ALOG(LOG_VERBOSE, SQLITE_TRACE_TAG, "%s: \"%s\"\n",
+            connection->label.string(), sql);
+}
+
+// Called each time a statement finishes execution, when profiling is enabled.
+static void sqliteProfileCallback(void *data, const char *sql, sqlite3_uint64 tm) {
+    SQLiteConnection* connection = static_cast<SQLiteConnection*>(data);
+    ALOG(LOG_VERBOSE, SQLITE_PROFILE_TAG, "%s: \"%s\" took %0.3f ms\n",
+            connection->label.string(), sql, tm * 0.000001f);
+}
+
+
+static jint nativeOpen(JNIEnv* env, jclass clazz, jstring pathStr, jint openFlags,
+        jstring labelStr, jboolean enableTrace, jboolean enableProfile) {
+    int sqliteFlags;
+    if (openFlags & SQLiteConnection::CREATE_IF_NECESSARY) {
+        sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
+    } else if (openFlags & SQLiteConnection::OPEN_READONLY) {
+        sqliteFlags = SQLITE_OPEN_READONLY;
+    } else {
+        sqliteFlags = SQLITE_OPEN_READWRITE;
+    }
+
+    const char* pathChars = env->GetStringUTFChars(pathStr, NULL);
+    String8 path(pathChars);
+    env->ReleaseStringUTFChars(pathStr, pathChars);
+
+    const char* labelChars = env->GetStringUTFChars(labelStr, NULL);
+    String8 label(labelChars);
+    env->ReleaseStringUTFChars(labelStr, labelChars);
+
+    sqlite3* db;
+    int err = sqlite3_open_v2(path.string(), &db, sqliteFlags, NULL);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception_errcode(env, err, "Could not open database");
+        return 0;
+    }
+
+    // Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
+    err = sqlite3_busy_timeout(db, 1000 /* ms */);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, db, "Could not set busy timeout");
+        sqlite3_close(db);
+        return 0;
+    }
+
+    // Enable WAL auto-checkpointing after a commit whenever at least one frame is in the log.
+    // This ensures that a checkpoint will occur after each transaction if needed.
+    err = sqlite3_wal_autocheckpoint(db, 1);
+    if (err) {
+        throw_sqlite3_exception(env, db, "Could not enable auto-checkpointing.");
+        sqlite3_close(db);
+        return 0;
+    }
+
+    // Register custom Android functions.
+    err = register_android_functions(db, UTF16_STORAGE);
+    if (err) {
+        throw_sqlite3_exception(env, db, "Could not register Android SQL functions.");
+        sqlite3_close(db);
+        return 0;
+    }
+
+    // Create wrapper object.
+    SQLiteConnection* connection = new SQLiteConnection(db, openFlags, path, label);
+
+    // Enable tracing and profiling if requested.
+    if (enableTrace) {
+        sqlite3_trace(db, &sqliteTraceCallback, connection);
+    }
+    if (enableProfile) {
+        sqlite3_profile(db, &sqliteProfileCallback, connection);
+    }
+
+    ALOGV("Opened connection %p with label '%s'", db, label.string());
+    return reinterpret_cast<jint>(connection);
+}
+
+static void nativeClose(JNIEnv* env, jclass clazz, jint connectionPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+
+    if (connection) {
+        ALOGV("Closing connection %p", connection->db);
+        int err = sqlite3_close(connection->db);
+        if (err != SQLITE_OK) {
+            // This can happen if sub-objects aren't closed first.  Make sure the caller knows.
+            ALOGE("sqlite3_close(%p) failed: %d", connection->db, err);
+            throw_sqlite3_exception(env, connection->db, "Count not close db.");
+            return;
+        }
+
+        delete connection;
+    }
+}
+
+// Called each time a custom function is evaluated.
+static void sqliteCustomFunctionCallback(sqlite3_context *context,
+        int argc, sqlite3_value **argv) {
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+
+    // Get the callback function object.
+    // Create a new local reference to it in case the callback tries to do something
+    // dumb like unregister the function (thereby destroying the global ref) while it is running.
+    jobject functionObjGlobal = reinterpret_cast<jobject>(sqlite3_user_data(context));
+    jobject functionObj = env->NewLocalRef(functionObjGlobal);
+
+    jobjectArray argsArray = env->NewObjectArray(argc, gStringClassInfo.clazz, NULL);
+    if (argsArray) {
+        for (int i = 0; i < argc; i++) {
+            const jchar* arg = static_cast<const jchar*>(sqlite3_value_text16(argv[i]));
+            if (!arg) {
+                ALOGW("NULL argument in custom_function_callback.  This should not happen.");
+            } else {
+                size_t argLen = sqlite3_value_bytes16(argv[i]) / sizeof(jchar);
+                jstring argStr = env->NewString(arg, argLen);
+                if (!argStr) {
+                    goto error; // out of memory error
+                }
+                env->SetObjectArrayElement(argsArray, i, argStr);
+                env->DeleteLocalRef(argStr);
+            }
+        }
+
+        // TODO: Support functions that return values.
+        env->CallVoidMethod(functionObj,
+                gSQLiteCustomFunctionClassInfo.dispatchCallback, argsArray);
+
+error:
+        env->DeleteLocalRef(argsArray);
+    }
+
+    env->DeleteLocalRef(functionObj);
+
+    if (env->ExceptionCheck()) {
+        ALOGE("An exception was thrown by custom SQLite function.");
+        LOGE_EX(env);
+        env->ExceptionClear();
+    }
+}
+
+// Called when a custom function is destroyed.
+static void sqliteCustomFunctionDestructor(void* data) {
+    jobject functionObjGlobal = reinterpret_cast<jobject>(data);
+
+    JNIEnv* env = AndroidRuntime::getJNIEnv();
+    env->DeleteGlobalRef(functionObjGlobal);
+}
+
+static void nativeRegisterCustomFunction(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jobject functionObj) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+
+    jstring nameStr = jstring(env->GetObjectField(
+            functionObj, gSQLiteCustomFunctionClassInfo.name));
+    jint numArgs = env->GetIntField(functionObj, gSQLiteCustomFunctionClassInfo.numArgs);
+
+    jobject functionObjGlobal = env->NewGlobalRef(functionObj);
+
+    const char* name = env->GetStringUTFChars(nameStr, NULL);
+    int err = sqlite3_create_function_v2(connection->db, name, numArgs, SQLITE_UTF16,
+            reinterpret_cast<void*>(functionObjGlobal),
+            &sqliteCustomFunctionCallback, NULL, NULL, &sqliteCustomFunctionDestructor);
+    env->ReleaseStringUTFChars(nameStr, name);
+
+    if (err != SQLITE_OK) {
+        ALOGE("sqlite3_create_function returned %d", err);
+        env->DeleteGlobalRef(functionObjGlobal);
+        throw_sqlite3_exception(env, connection->db);
+        return;
+    }
+}
+
+// Set locale in the android_metadata table, install localized collators, and rebuild indexes
+static void nativeSetLocale(JNIEnv* env, jclass clazz, jint connectionPtr, jstring localeStr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+
+    if (connection->openFlags & SQLiteConnection::NO_LOCALIZED_COLLATORS) {
+        // We should probably throw IllegalStateException but the contract for
+        // setLocale says that we just do nothing.  Oh well.
+        return;
+    }
+
+    int err;
+    char const* locale = env->GetStringUTFChars(localeStr, NULL);
+    sqlite3_stmt* stmt = NULL;
+    char** meta = NULL;
+    int rowCount, colCount;
+    char* dbLocale = NULL;
+
+    // create the table, if necessary and possible
+    if (!(connection->openFlags & SQLiteConnection::OPEN_READONLY)) {
+        err = sqlite3_exec(connection->db,
+                "CREATE TABLE IF NOT EXISTS " ANDROID_TABLE " (locale TEXT)",
+                NULL, NULL, NULL);
+        if (err != SQLITE_OK) {
+            ALOGE("CREATE TABLE " ANDROID_TABLE " failed");
+            throw_sqlite3_exception(env, connection->db);
+            goto done;
+        }
+    }
+
+    // try to read from the table
+    err = sqlite3_get_table(connection->db,
+            "SELECT locale FROM " ANDROID_TABLE " LIMIT 1",
+            &meta, &rowCount, &colCount, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("SELECT locale FROM " ANDROID_TABLE " failed");
+        throw_sqlite3_exception(env, connection->db);
+        goto done;
+    }
+
+    dbLocale = (rowCount >= 1) ? meta[colCount] : NULL;
+
+    if (dbLocale != NULL && !strcmp(dbLocale, locale)) {
+        // database locale is the same as the desired locale; set up the collators and go
+        err = register_localized_collators(connection->db, locale, UTF16_STORAGE);
+        if (err != SQLITE_OK) {
+            throw_sqlite3_exception(env, connection->db);
+        }
+        goto done;   // no database changes needed
+    }
+
+    if (connection->openFlags & SQLiteConnection::OPEN_READONLY) {
+        // read-only database, so we're going to have to put up with whatever we got
+        // For registering new index. Not for modifing the read-only database.
+        err = register_localized_collators(connection->db, locale, UTF16_STORAGE);
+        if (err != SQLITE_OK) {
+            throw_sqlite3_exception(env, connection->db);
+        }
+        goto done;
+    }
+
+    // need to update android_metadata and indexes atomically, so use a transaction...
+    err = sqlite3_exec(connection->db, "BEGIN TRANSACTION", NULL, NULL, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("BEGIN TRANSACTION failed setting locale");
+        throw_sqlite3_exception(env, connection->db);
+        goto done;
+    }
+
+    err = register_localized_collators(connection->db, locale, UTF16_STORAGE);
+    if (err != SQLITE_OK) {
+        ALOGE("register_localized_collators() failed setting locale");
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    err = sqlite3_exec(connection->db, "DELETE FROM " ANDROID_TABLE, NULL, NULL, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("DELETE failed setting locale");
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    static const char *sql = "INSERT INTO " ANDROID_TABLE " (locale) VALUES(?);";
+    err = sqlite3_prepare_v2(connection->db, sql, -1, &stmt, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("sqlite3_prepare_v2(\"%s\") failed", sql);
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    err = sqlite3_bind_text(stmt, 1, locale, -1, SQLITE_TRANSIENT);
+    if (err != SQLITE_OK) {
+        ALOGE("sqlite3_bind_text() failed setting locale");
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    err = sqlite3_step(stmt);
+    if (err != SQLITE_OK && err != SQLITE_DONE) {
+        ALOGE("sqlite3_step(\"%s\") failed setting locale", sql);
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    err = sqlite3_exec(connection->db, "REINDEX LOCALIZED", NULL, NULL, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("REINDEX LOCALIZED failed");
+        throw_sqlite3_exception(env, connection->db);
+        goto rollback;
+    }
+
+    // all done, yay!
+    err = sqlite3_exec(connection->db, "COMMIT TRANSACTION", NULL, NULL, NULL);
+    if (err != SQLITE_OK) {
+        ALOGE("COMMIT TRANSACTION failed setting locale");
+        throw_sqlite3_exception(env, connection->db);
+        goto done;
+    }
+
+rollback:
+    if (err != SQLITE_OK) {
+        sqlite3_exec(connection->db, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
+    }
+
+done:
+    if (stmt) {
+        sqlite3_finalize(stmt);
+    }
+    if (meta) {
+        sqlite3_free_table(meta);
+    }
+    if (locale) {
+        env->ReleaseStringUTFChars(localeStr, locale);
+    }
+}
+
+static jint nativePrepareStatement(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jstring sqlString) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+
+    jsize sqlLength = env->GetStringLength(sqlString);
+    const jchar* sql = env->GetStringCritical(sqlString, NULL);
+    sqlite3_stmt* statement;
+    int err = sqlite3_prepare16_v2(connection->db,
+            sql, sqlLength * sizeof(jchar), &statement, NULL);
+    env->ReleaseStringCritical(sqlString, sql);
+
+    if (err != SQLITE_OK) {
+        // Error messages like 'near ")": syntax error' are not
+        // always helpful enough, so construct an error string that
+        // includes the query itself.
+        const char *query = env->GetStringUTFChars(sqlString, NULL);
+        char *message = (char*) malloc(strlen(query) + 50);
+        if (message) {
+            strcpy(message, ", while compiling: "); // less than 50 chars
+            strcat(message, query);
+        }
+        env->ReleaseStringUTFChars(sqlString, query);
+        throw_sqlite3_exception(env, connection->db, message);
+        free(message);
+        return 0;
+    }
+
+    ALOGV("Prepared statement %p on connection %p", statement, connection->db);
+    return reinterpret_cast<jint>(statement);
+}
+
+static void nativeFinalizeStatement(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    ALOGV("Finalized statement %p on connection %p", statement, connection->db);
+    int err = sqlite3_finalize(statement);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static jint nativeGetParameterCount(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    return sqlite3_bind_parameter_count(statement);
+}
+
+static jboolean nativeIsReadOnly(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    return sqlite3_stmt_readonly(statement) != 0;
+}
+
+static jint nativeGetColumnCount(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    return sqlite3_column_count(statement);
+}
+
+static jstring nativeGetColumnName(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    const jchar* name = static_cast<const jchar*>(sqlite3_column_name16(statement, index));
+    if (name) {
+        size_t length = 0;
+        while (name[length]) {
+            length += 1;
+        }
+        return env->NewString(name, length);
+    }
+    return NULL;
+}
+
+static void nativeBindNull(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = sqlite3_bind_null(statement, index);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static void nativeBindLong(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index, jlong value) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = sqlite3_bind_int64(statement, index, value);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static void nativeBindDouble(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index, jdouble value) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = sqlite3_bind_double(statement, index, value);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static void nativeBindString(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index, jstring valueString) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    jsize valueLength = env->GetStringLength(valueString);
+    const jchar* value = env->GetStringCritical(valueString, NULL);
+    int err = sqlite3_bind_text16(statement, index, value, valueLength * sizeof(jchar),
+            SQLITE_TRANSIENT);
+    env->ReleaseStringCritical(valueString, value);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static void nativeBindBlob(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr, jint index, jbyteArray valueArray) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    jsize valueLength = env->GetArrayLength(valueArray);
+    jbyte* value = static_cast<jbyte*>(env->GetPrimitiveArrayCritical(valueArray, NULL));
+    int err = sqlite3_bind_blob(statement, index, value, valueLength, SQLITE_TRANSIENT);
+    env->ReleasePrimitiveArrayCritical(valueArray, value, JNI_ABORT);
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static void nativeResetStatementAndClearBindings(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = sqlite3_reset(statement);
+    if (err == SQLITE_OK) {
+        err = sqlite3_clear_bindings(statement);
+    }
+    if (err != SQLITE_OK) {
+        throw_sqlite3_exception(env, connection->db, NULL);
+    }
+}
+
+static int executeNonQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement) {
+    int err = sqlite3_step(statement);
+    if (err == SQLITE_ROW) {
+        throw_sqlite3_exception(env,
+                "Queries can be performed using SQLiteDatabase query or rawQuery methods only.");
+    } else if (err != SQLITE_DONE) {
+        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(connection->db));
+    }
+    return err;
+}
+
+static void nativeExecute(JNIEnv* env, jclass clazz, jint connectionPtr,
+        jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    executeNonQuery(env, connection, statement);
+}
+
+static jint nativeExecuteForChangedRowCount(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = executeNonQuery(env, connection, statement);
+    return err == SQLITE_DONE ? sqlite3_changes(connection->db) : -1;
+}
+
+static jlong nativeExecuteForLastInsertedRowId(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = executeNonQuery(env, connection, statement);
+    return err == SQLITE_DONE && sqlite3_changes(connection->db) > 0
+            ? sqlite3_last_insert_rowid(connection->db) : -1;
+}
+
+static int executeOneRowQuery(JNIEnv* env, SQLiteConnection* connection, sqlite3_stmt* statement) {
+    int err = sqlite3_step(statement);
+    if (err != SQLITE_ROW) {
+        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(connection->db));
+    }
+    return err;
+}
+
+static jlong nativeExecuteForLong(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = executeOneRowQuery(env, connection, statement);
+    if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) {
+        return sqlite3_column_int64(statement, 0);
+    }
+    return -1;
+}
+
+static jstring nativeExecuteForString(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = executeOneRowQuery(env, connection, statement);
+    if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) {
+        const jchar* text = static_cast<const jchar*>(sqlite3_column_text16(statement, 0));
+        if (text) {
+            size_t length = sqlite3_column_bytes16(statement, 0) / sizeof(jchar);
+            return env->NewString(text, length);
+        }
+    }
+    return NULL;
+}
+
+static int createAshmemRegionWithData(JNIEnv* env, const void* data, size_t length) {
+    int error = 0;
+    int fd = ashmem_create_region(NULL, length);
+    if (fd < 0) {
+        error = errno;
+        ALOGE("ashmem_create_region failed: %s", strerror(error));
+    } else {
+        if (length > 0) {
+            void* ptr = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
+            if (ptr == MAP_FAILED) {
+                error = errno;
+                ALOGE("mmap failed: %s", strerror(error));
+            } else {
+                memcpy(ptr, data, length);
+                munmap(ptr, length);
+            }
+        }
+
+        if (!error) {
+            if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
+                error = errno;
+                ALOGE("ashmem_set_prot_region failed: %s", strerror(errno));
+            } else {
+                return fd;
+            }
+        }
+
+        close(fd);
+    }
+
+    jniThrowIOException(env, error);
+    return -1;
+}
+
+static jint nativeExecuteForBlobFileDescriptor(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+
+    int err = executeOneRowQuery(env, connection, statement);
+    if (err == SQLITE_ROW && sqlite3_column_count(statement) >= 1) {
+        const void* blob = sqlite3_column_blob(statement, 0);
+        if (blob) {
+            int length = sqlite3_column_bytes(statement, 0);
+            if (length >= 0) {
+                return createAshmemRegionWithData(env, blob, length);
+            }
+        }
+    }
+    return -1;
+}
+
+enum CopyRowResult {
+    CPR_OK,
+    CPR_FULL,
+    CPR_ERROR,
+};
+
+static CopyRowResult copyRow(JNIEnv* env, CursorWindow* window,
+        sqlite3_stmt* statement, int numColumns, int startPos, int addedRows) {
+    // Allocate a new field directory for the row.
+    status_t status = window->allocRow();
+    if (status) {
+        LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d, error=%d",
+                startPos, addedRows, status);
+        return CPR_FULL;
+    }
+
+    // Pack the row into the window.
+    CopyRowResult result = CPR_OK;
+    for (int i = 0; i < numColumns; i++) {
+        int type = sqlite3_column_type(statement, i);
+        if (type == SQLITE_TEXT) {
+            // TEXT data
+            const char* text = reinterpret_cast<const char*>(
+                    sqlite3_column_text(statement, i));
+            // SQLite does not include the NULL terminator in size, but does
+            // ensure all strings are NULL terminated, so increase size by
+            // one to make sure we store the terminator.
+            size_t sizeIncludingNull = sqlite3_column_bytes(statement, i) + 1;
+            status = window->putString(addedRows, i, text, sizeIncludingNull);
+            if (status) {
+                LOG_WINDOW("Failed allocating %u bytes for text at %d,%d, error=%d",
+                        sizeIncludingNull, startPos + addedRows, i, status);
+                result = CPR_FULL;
+                break;
+            }
+            LOG_WINDOW("%d,%d is TEXT with %u bytes",
+                    startPos + addedRows, i, sizeIncludingNull);
+        } else if (type == SQLITE_INTEGER) {
+            // INTEGER data
+            int64_t value = sqlite3_column_int64(statement, i);
+            status = window->putLong(addedRows, i, value);
+            if (status) {
+                LOG_WINDOW("Failed allocating space for a long in column %d, error=%d",
+                        i, status);
+                result = CPR_FULL;
+                break;
+            }
+            LOG_WINDOW("%d,%d is INTEGER 0x%016llx", startPos + addedRows, i, value);
+        } else if (type == SQLITE_FLOAT) {
+            // FLOAT data
+            double value = sqlite3_column_double(statement, i);
+            status = window->putDouble(addedRows, i, value);
+            if (status) {
+                LOG_WINDOW("Failed allocating space for a double in column %d, error=%d",
+                        i, status);
+                result = CPR_FULL;
+                break;
+            }
+            LOG_WINDOW("%d,%d is FLOAT %lf", startPos + addedRows, i, value);
+        } else if (type == SQLITE_BLOB) {
+            // BLOB data
+            const void* blob = sqlite3_column_blob(statement, i);
+            size_t size = sqlite3_column_bytes(statement, i);
+            status = window->putBlob(addedRows, i, blob, size);
+            if (status) {
+                LOG_WINDOW("Failed allocating %u bytes for blob at %d,%d, error=%d",
+                        size, startPos + addedRows, i, status);
+                result = CPR_FULL;
+                break;
+            }
+            LOG_WINDOW("%d,%d is Blob with %u bytes",
+                    startPos + addedRows, i, size);
+        } else if (type == SQLITE_NULL) {
+            // NULL field
+            status = window->putNull(addedRows, i);
+            if (status) {
+                LOG_WINDOW("Failed allocating space for a null in column %d, error=%d",
+                        i, status);
+                result = CPR_FULL;
+                break;
+            }
+
+            LOG_WINDOW("%d,%d is NULL", startPos + addedRows, i);
+        } else {
+            // Unknown data
+            ALOGE("Unknown column type when filling database window");
+            throw_sqlite3_exception(env, "Unknown column type when filling window");
+            result = CPR_ERROR;
+            break;
+        }
+    }
+
+    // Free the last row if if was not successfully copied.
+    if (result != CPR_OK) {
+        window->freeLastRow();
+    }
+    return result;
+}
+
+static jlong nativeExecuteForCursorWindow(JNIEnv* env, jclass clazz,
+        jint connectionPtr, jint statementPtr, jint windowPtr,
+        jint startPos, jint requiredPos, jboolean countAllRows) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
+    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
+
+    status_t status = window->clear();
+    if (status) {
+        String8 msg;
+        msg.appendFormat("Failed to clear the cursor window, status=%d", status);
+        throw_sqlite3_exception(env, connection->db, msg.string());
+        return 0;
+    }
+
+    int numColumns = sqlite3_column_count(statement);
+    status = window->setNumColumns(numColumns);
+    if (status) {
+        String8 msg;
+        msg.appendFormat("Failed to set the cursor window column count to %d, status=%d",
+                numColumns, status);
+        throw_sqlite3_exception(env, connection->db, msg.string());
+        return 0;
+    }
+
+    int retryCount = 0;
+    int totalRows = 0;
+    int addedRows = 0;
+    bool windowFull = false;
+    bool gotException = false;
+    while (!gotException && (!windowFull || countAllRows)) {
+        int err = sqlite3_step(statement);
+        if (err == SQLITE_ROW) {
+            LOG_WINDOW("Stepped statement %p to row %d", statement, totalRows);
+            retryCount = 0;
+            totalRows += 1;
+
+            // Skip the row if the window is full or we haven't reached the start position yet.
+            if (startPos >= totalRows || windowFull) {
+                continue;
+            }
+
+            CopyRowResult cpr = copyRow(env, window, statement, numColumns, startPos, addedRows);
+            if (cpr == CPR_FULL && addedRows && startPos + addedRows < requiredPos) {
+                // We filled the window before we got to the one row that we really wanted.
+                // Clear the window and start filling it again from here.
+                // TODO: Would be nicer if we could progressively replace earlier rows.
+                window->clear();
+                window->setNumColumns(numColumns);
+                startPos += addedRows;
+                addedRows = 0;
+                cpr = copyRow(env, window, statement, numColumns, startPos, addedRows);
+            }
+
+            if (cpr == CPR_OK) {
+                addedRows += 1;
+            } else if (cpr == CPR_FULL) {
+                windowFull = true;
+            } else {
+                gotException = true;
+            }
+        } else if (err == SQLITE_DONE) {
+            // All rows processed, bail
+            LOG_WINDOW("Processed all rows");
+            break;
+        } else if (err == SQLITE_LOCKED || err == SQLITE_BUSY) {
+            // The table is locked, retry
+            LOG_WINDOW("Database locked, retrying");
+            if (retryCount > 50) {
+                ALOGE("Bailing on database busy retry");
+                throw_sqlite3_exception(env, connection->db, "retrycount exceeded");
+                gotException = true;
+            } else {
+                // Sleep to give the thread holding the lock a chance to finish
+                usleep(1000);
+                retryCount++;
+            }
+        } else {
+            throw_sqlite3_exception(env, connection->db);
+            gotException = true;
+        }
+    }
+
+    LOG_WINDOW("Resetting statement %p after fetching %d rows and adding %d rows"
+            "to the window in %d bytes",
+            statement, totalRows, addedRows, window->size() - window->freeSpace());
+    sqlite3_reset(statement);
+
+    // Report the total number of rows on request.
+    if (startPos > totalRows) {
+        ALOGE("startPos %d > actual rows %d", startPos, totalRows);
+    }
+    jlong result = jlong(startPos) << 32 | jlong(totalRows);
+    return result;
+}
+
+static jint nativeGetDbLookaside(JNIEnv* env, jobject clazz, jint connectionPtr) {
+    SQLiteConnection* connection = reinterpret_cast<SQLiteConnection*>(connectionPtr);
+
+    int cur = -1;
+    int unused;
+    sqlite3_db_status(connection->db, SQLITE_DBSTATUS_LOOKASIDE_USED, &cur, &unused, 0);
+    return cur;
+}
+
+
+static JNINativeMethod sMethods[] =
+{
+    /* name, signature, funcPtr */
+    { "nativeOpen", "(Ljava/lang/String;ILjava/lang/String;ZZ)I",
+            (void*)nativeOpen },
+    { "nativeClose", "(I)V",
+            (void*)nativeClose },
+    { "nativeRegisterCustomFunction", "(ILandroid/database/sqlite/SQLiteCustomFunction;)V",
+            (void*)nativeRegisterCustomFunction },
+    { "nativeSetLocale", "(ILjava/lang/String;)V",
+            (void*)nativeSetLocale },
+    { "nativePrepareStatement", "(ILjava/lang/String;)I",
+            (void*)nativePrepareStatement },
+    { "nativeFinalizeStatement", "(II)V",
+            (void*)nativeFinalizeStatement },
+    { "nativeGetParameterCount", "(II)I",
+            (void*)nativeGetParameterCount },
+    { "nativeIsReadOnly", "(II)Z",
+            (void*)nativeIsReadOnly },
+    { "nativeGetColumnCount", "(II)I",
+            (void*)nativeGetColumnCount },
+    { "nativeGetColumnName", "(III)Ljava/lang/String;",
+            (void*)nativeGetColumnName },
+    { "nativeBindNull", "(III)V",
+            (void*)nativeBindNull },
+    { "nativeBindLong", "(IIIJ)V",
+            (void*)nativeBindLong },
+    { "nativeBindDouble", "(IIID)V",
+            (void*)nativeBindDouble },
+    { "nativeBindString", "(IIILjava/lang/String;)V",
+            (void*)nativeBindString },
+    { "nativeBindBlob", "(III[B)V",
+            (void*)nativeBindBlob },
+    { "nativeResetStatementAndClearBindings", "(II)V",
+            (void*)nativeResetStatementAndClearBindings },
+    { "nativeExecute", "(II)V",
+            (void*)nativeExecute },
+    { "nativeExecuteForLong", "(II)J",
+            (void*)nativeExecuteForLong },
+    { "nativeExecuteForString", "(II)Ljava/lang/String;",
+            (void*)nativeExecuteForString },
+    { "nativeExecuteForBlobFileDescriptor", "(II)I",
+            (void*)nativeExecuteForBlobFileDescriptor },
+    { "nativeExecuteForChangedRowCount", "(II)I",
+            (void*)nativeExecuteForChangedRowCount },
+    { "nativeExecuteForLastInsertedRowId", "(II)J",
+            (void*)nativeExecuteForLastInsertedRowId },
+    { "nativeExecuteForCursorWindow", "(IIIIIZ)J",
+            (void*)nativeExecuteForCursorWindow },
+    { "nativeGetDbLookaside", "(I)I",
+            (void*)nativeGetDbLookaside },
+};
+
+#define FIND_CLASS(var, className) \
+        var = env->FindClass(className); \
+        LOG_FATAL_IF(! var, "Unable to find class " className);
+
+#define GET_METHOD_ID(var, clazz, methodName, fieldDescriptor) \
+        var = env->GetMethodID(clazz, methodName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find method" methodName);
+
+#define GET_FIELD_ID(var, clazz, fieldName, fieldDescriptor) \
+        var = env->GetFieldID(clazz, fieldName, fieldDescriptor); \
+        LOG_FATAL_IF(! var, "Unable to find field " fieldName);
+
+int register_android_database_SQLiteConnection(JNIEnv *env)
+{
+    jclass clazz;
+    FIND_CLASS(clazz, "android/database/sqlite/SQLiteCustomFunction");
+
+    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.name, clazz,
+            "name", "Ljava/lang/String;");
+    GET_FIELD_ID(gSQLiteCustomFunctionClassInfo.numArgs, clazz,
+            "numArgs", "I");
+    GET_METHOD_ID(gSQLiteCustomFunctionClassInfo.dispatchCallback,
+            clazz, "dispatchCallback", "([Ljava/lang/String;)V");
+
+    FIND_CLASS(clazz, "java/lang/String");
+    gStringClassInfo.clazz = jclass(env->NewGlobalRef(clazz));
+
+    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteConnection",
+            sMethods, NELEM(sMethods));
+}
+
+} // namespace android
diff --git a/core/jni/android_database_SQLiteDatabase.cpp b/core/jni/android_database_SQLiteDatabase.cpp
deleted file mode 100644
index 28c421d..0000000
--- a/core/jni/android_database_SQLiteDatabase.cpp
+++ /dev/null
@@ -1,636 +0,0 @@
-/*
- * Copyright (C) 2006-2007 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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "SqliteDatabaseCpp"
-
-#include <utils/Log.h>
-#include <utils/String8.h>
-#include <utils/String16.h>
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-#include <sqlite3_android.h>
-#include <string.h>
-#include <utils/Log.h>
-#include <utils/threads.h>
-#include <utils/List.h>
-#include <utils/Errors.h>
-#include <ctype.h>
-
-#include <stdio.h>
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <netdb.h>
-#include <sys/ioctl.h>
-
-#include "sqlite3_exception.h"
-
-#define UTF16_STORAGE 0
-#define INVALID_VERSION -1
-#define ANDROID_TABLE "android_metadata"
-/* uncomment the next line to force-enable logging of all statements */
-// #define DB_LOG_STATEMENTS
-
-#define DEBUG_JNI 0
-
-namespace android {
-
-enum {
-    OPEN_READWRITE          = 0x00000000,
-    OPEN_READONLY           = 0x00000001,
-    OPEN_READ_MASK          = 0x00000001,
-    NO_LOCALIZED_COLLATORS  = 0x00000010,
-    CREATE_IF_NECESSARY     = 0x10000000
-};
-
-static jfieldID offset_db_handle;
-static jmethodID method_custom_function_callback;
-static jclass string_class;
-static jint sSqliteSoftHeapLimit = 0;
-
-static char *createStr(const char *path, short extra) {
-    int len = strlen(path) + extra;
-    char *str = (char *)malloc(len + 1);
-    strncpy(str, path, len);
-    str[len] = NULL;
-    return str;
-}
-
-static void sqlLogger(void *databaseName, int iErrCode, const char *zMsg) {
-    // skip printing this message if it is due to certain types of errors
-    if (iErrCode == 0 || iErrCode == SQLITE_CONSTRAINT) return;
-    // print databasename, errorcode and msg
-    ALOGI("sqlite returned: error code = %d, msg = %s, db=%s\n", iErrCode, zMsg, databaseName);
-}
-
-// register the logging func on sqlite. needs to be done BEFORE any sqlite3 func is called.
-static void registerLoggingFunc(const char *path) {
-    static bool loggingFuncSet = false;
-    if (loggingFuncSet) {
-        return;
-    }
-
-    ALOGV("Registering sqlite logging func \n");
-    int err = sqlite3_config(SQLITE_CONFIG_LOG, &sqlLogger, (void *)createStr(path, 0));
-    if (err != SQLITE_OK) {
-        ALOGW("sqlite returned error = %d when trying to register logging func.\n", err);
-        return;
-    }
-    loggingFuncSet = true;
-}
-
-/* public native void dbopen(String path, int flags, String locale); */
-static void dbopen(JNIEnv* env, jobject object, jstring pathString, jint flags)
-{
-    int err;
-    sqlite3 * handle = NULL;
-    sqlite3_stmt * statement = NULL;
-    char const * path8 = env->GetStringUTFChars(pathString, NULL);
-    int sqliteFlags;
-
-    // register the logging func on sqlite. needs to be done BEFORE any sqlite3 func is called.
-    registerLoggingFunc(path8);
-
-    // convert our flags into the sqlite flags
-    if (flags & CREATE_IF_NECESSARY) {
-        sqliteFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE;
-    } else if (flags & OPEN_READONLY) {
-        sqliteFlags = SQLITE_OPEN_READONLY;
-    } else {
-        sqliteFlags = SQLITE_OPEN_READWRITE;
-    }
-
-    err = sqlite3_open_v2(path8, &handle, sqliteFlags, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("sqlite3_open_v2(\"%s\", &handle, %d, NULL) failed\n", path8, sqliteFlags);
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    // The soft heap limit prevents the page cache allocations from growing
-    // beyond the given limit, no matter what the max page cache sizes are
-    // set to. The limit does not, as of 3.5.0, affect any other allocations.
-    sqlite3_soft_heap_limit(sSqliteSoftHeapLimit);
-
-    // Set the default busy handler to retry for 1000ms and then return SQLITE_BUSY
-    err = sqlite3_busy_timeout(handle, 1000 /* ms */);
-    if (err != SQLITE_OK) {
-        ALOGE("sqlite3_busy_timeout(handle, 1000) failed for \"%s\"\n", path8);
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-#ifdef DB_INTEGRITY_CHECK
-    static const char* integritySql = "pragma integrity_check(1);";
-    err = sqlite3_prepare_v2(handle, integritySql, -1, &statement, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("sqlite_prepare_v2(handle, \"%s\") failed for \"%s\"\n", integritySql, path8);
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    // first is OK or error message
-    err = sqlite3_step(statement);
-    if (err != SQLITE_ROW) {
-        ALOGE("integrity check failed for \"%s\"\n", integritySql, path8);
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    } else {
-        const char *text = (const char*)sqlite3_column_text(statement, 0);
-        if (strcmp(text, "ok") != 0) {
-            ALOGE("integrity check failed for \"%s\": %s\n", integritySql, path8, text);
-            jniThrowException(env, "android/database/sqlite/SQLiteDatabaseCorruptException", text);
-            goto done;
-        }
-    }
-#endif
-
-    err = register_android_functions(handle, UTF16_STORAGE);
-    if (err) {
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    ALOGV("Opened '%s' - %p\n", path8, handle);
-    env->SetIntField(object, offset_db_handle, (int) handle);
-    handle = NULL;  // The caller owns the handle now.
-
-done:
-    // Release allocated resources
-    if (path8 != NULL) env->ReleaseStringUTFChars(pathString, path8);
-    if (statement != NULL) sqlite3_finalize(statement);
-    if (handle != NULL) sqlite3_close(handle);
-}
-
-static char *getDatabaseName(JNIEnv* env, sqlite3 * handle, jstring databaseName, short connNum) {
-    char const *path = env->GetStringUTFChars(databaseName, NULL);
-    if (path == NULL) {
-        ALOGE("Failure in getDatabaseName(). VM ran out of memory?\n");
-        return NULL; // VM would have thrown OutOfMemoryError
-    }
-    char *dbNameStr = createStr(path, 4);
-    if (connNum > 999) { // TODO: if number of pooled connections > 999, fix this line.
-      connNum = -1;
-    }
-    sprintf(dbNameStr + strlen(path), "|%03d", connNum);
-    env->ReleaseStringUTFChars(databaseName, path);
-    return dbNameStr;
-}
-
-static void sqlTrace(void *databaseName, const char *sql) {
-    ALOGI("sql_statement|%s|%s\n", (char *)databaseName, sql);
-}
-
-/* public native void enableSqlTracing(); */
-static void enableSqlTracing(JNIEnv* env, jobject object, jstring databaseName, jshort connType)
-{
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-    sqlite3_trace(handle, &sqlTrace, (void *)getDatabaseName(env, handle, databaseName, connType));
-}
-
-static void sqlProfile(void *databaseName, const char *sql, sqlite3_uint64 tm) {
-    double d = tm/1000000.0;
-    ALOGI("elapsedTime4Sql|%s|%.3f ms|%s\n", (char *)databaseName, d, sql);
-}
-
-/* public native void enableSqlProfiling(); */
-static void enableSqlProfiling(JNIEnv* env, jobject object, jstring databaseName, jshort connType)
-{
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-    sqlite3_profile(handle, &sqlProfile, (void *)getDatabaseName(env, handle, databaseName,
-            connType));
-}
-
-/* public native void close(); */
-static void dbclose(JNIEnv* env, jobject object)
-{
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-
-    if (handle != NULL) {
-        // release the memory associated with the traceFuncArg in enableSqlTracing function
-        void *traceFuncArg = sqlite3_trace(handle, &sqlTrace, NULL);
-        if (traceFuncArg != NULL) {
-            free(traceFuncArg);
-        }
-        // release the memory associated with the traceFuncArg in enableSqlProfiling function
-        traceFuncArg = sqlite3_profile(handle, &sqlProfile, NULL);
-        if (traceFuncArg != NULL) {
-            free(traceFuncArg);
-        }
-        ALOGV("Closing database: handle=%p\n", handle);
-        int result = sqlite3_close(handle);
-        if (result == SQLITE_OK) {
-            ALOGV("Closed %p\n", handle);
-            env->SetIntField(object, offset_db_handle, 0);
-        } else {
-            // This can happen if sub-objects aren't closed first.  Make sure the caller knows.
-            throw_sqlite3_exception(env, handle);
-            ALOGE("sqlite3_close(%p) failed: %d\n", handle, result);
-        }
-    }
-}
-
-/* native int native_getDbLookaside(); */
-static jint native_getDbLookaside(JNIEnv* env, jobject object)
-{
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-    int pCur = -1;
-    int unused;
-    sqlite3_db_status(handle, SQLITE_DBSTATUS_LOOKASIDE_USED, &pCur, &unused, 0);
-    return pCur;
-}
-
-/* set locale in the android_metadata table, install localized collators, and rebuild indexes */
-static void native_setLocale(JNIEnv* env, jobject object, jstring localeString, jint flags)
-{
-    if ((flags & NO_LOCALIZED_COLLATORS)) return;
-
-    int err;
-    char const* locale8 = env->GetStringUTFChars(localeString, NULL);
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-    sqlite3_stmt* stmt = NULL;
-    char** meta = NULL;
-    int rowCount, colCount;
-    char* dbLocale = NULL;
-
-    // create the table, if necessary and possible
-    if (!(flags & OPEN_READONLY)) {
-        static const char *createSql ="CREATE TABLE IF NOT EXISTS " ANDROID_TABLE " (locale TEXT)";
-        err = sqlite3_exec(handle, createSql, NULL, NULL, NULL);
-        if (err != SQLITE_OK) {
-            ALOGE("CREATE TABLE " ANDROID_TABLE " failed\n");
-            throw_sqlite3_exception(env, handle);
-            goto done;
-        }
-    }
-
-    // try to read from the table
-    static const char *selectSql = "SELECT locale FROM " ANDROID_TABLE " LIMIT 1";
-    err = sqlite3_get_table(handle, selectSql, &meta, &rowCount, &colCount, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("SELECT locale FROM " ANDROID_TABLE " failed\n");
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    dbLocale = (rowCount >= 1) ? meta[colCount] : NULL;
-
-    if (dbLocale != NULL && !strcmp(dbLocale, locale8)) {
-        // database locale is the same as the desired locale; set up the collators and go
-        err = register_localized_collators(handle, locale8, UTF16_STORAGE);
-        if (err != SQLITE_OK) throw_sqlite3_exception(env, handle);
-        goto done;   // no database changes needed
-    }
-
-    if ((flags & OPEN_READONLY)) {
-        // read-only database, so we're going to have to put up with whatever we got
-        // For registering new index. Not for modifing the read-only database.
-        err = register_localized_collators(handle, locale8, UTF16_STORAGE);
-        if (err != SQLITE_OK) throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    // need to update android_metadata and indexes atomically, so use a transaction...
-    err = sqlite3_exec(handle, "BEGIN TRANSACTION", NULL, NULL, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("BEGIN TRANSACTION failed setting locale\n");
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-    err = register_localized_collators(handle, locale8, UTF16_STORAGE);
-    if (err != SQLITE_OK) {
-        ALOGE("register_localized_collators() failed setting locale\n");
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    err = sqlite3_exec(handle, "DELETE FROM " ANDROID_TABLE, NULL, NULL, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("DELETE failed setting locale\n");
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    static const char *sql = "INSERT INTO " ANDROID_TABLE " (locale) VALUES(?);";
-    err = sqlite3_prepare_v2(handle, sql, -1, &stmt, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("sqlite3_prepare_v2(\"%s\") failed\n", sql);
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    err = sqlite3_bind_text(stmt, 1, locale8, -1, SQLITE_TRANSIENT);
-    if (err != SQLITE_OK) {
-        ALOGE("sqlite3_bind_text() failed setting locale\n");
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    err = sqlite3_step(stmt);
-    if (err != SQLITE_OK && err != SQLITE_DONE) {
-        ALOGE("sqlite3_step(\"%s\") failed setting locale\n", sql);
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    err = sqlite3_exec(handle, "REINDEX LOCALIZED", NULL, NULL, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("REINDEX LOCALIZED failed\n");
-        throw_sqlite3_exception(env, handle);
-        goto rollback;
-    }
-
-    // all done, yay!
-    err = sqlite3_exec(handle, "COMMIT TRANSACTION", NULL, NULL, NULL);
-    if (err != SQLITE_OK) {
-        ALOGE("COMMIT TRANSACTION failed setting locale\n");
-        throw_sqlite3_exception(env, handle);
-        goto done;
-    }
-
-rollback:
-    if (err != SQLITE_OK) {
-        sqlite3_exec(handle, "ROLLBACK TRANSACTION", NULL, NULL, NULL);
-    }
-
-done:
-    if (locale8 != NULL) env->ReleaseStringUTFChars(localeString, locale8);
-    if (stmt != NULL) sqlite3_finalize(stmt);
-    if (meta != NULL) sqlite3_free_table(meta);
-}
-
-static void native_setSqliteSoftHeapLimit(JNIEnv* env, jobject clazz, jint limit) {
-    sSqliteSoftHeapLimit = limit;
-}
-
-static jint native_releaseMemory(JNIEnv *env, jobject clazz)
-{
-    // Attempt to release as much memory from the
-    return sqlite3_release_memory(sSqliteSoftHeapLimit);
-}
-
-static void native_finalize(JNIEnv* env, jobject object, jint statementId)
-{
-    if (statementId > 0) {
-        sqlite3_finalize((sqlite3_stmt *)statementId);
-    }
-}
-
-static void custom_function_callback(sqlite3_context * context, int argc, sqlite3_value ** argv) {
-    JNIEnv* env = AndroidRuntime::getJNIEnv();
-    if (!env) {
-        ALOGE("custom_function_callback cannot call into Java on this thread");
-        return;
-    }
-    // get global ref to CustomFunction object from our user data
-    jobject function = (jobject)sqlite3_user_data(context);
-
-    // pack up the arguments into a string array
-    jobjectArray strArray = env->NewObjectArray(argc, string_class, NULL);
-    if (!strArray)
-        goto done;
-    for (int i = 0; i < argc; i++) {
-        char* arg = (char *)sqlite3_value_text(argv[i]);
-        if (!arg) {
-            ALOGE("NULL argument in custom_function_callback.  This should not happen.");
-            return;
-        }
-        jobject obj = env->NewStringUTF(arg);
-        if (!obj)
-            goto done;
-        env->SetObjectArrayElement(strArray, i, obj);
-        env->DeleteLocalRef(obj);
-    }
-
-    env->CallVoidMethod(function, method_custom_function_callback, strArray);
-    env->DeleteLocalRef(strArray);
-
-done:
-    if (env->ExceptionCheck()) {
-        ALOGE("An exception was thrown by custom sqlite3 function.");
-        LOGE_EX(env);
-        env->ExceptionClear();
-    }
-}
-
-static jint native_addCustomFunction(JNIEnv* env, jobject object,
-        jstring name, jint numArgs, jobject function)
-{
-    sqlite3 * handle = (sqlite3 *)env->GetIntField(object, offset_db_handle);
-    char const *nameStr = env->GetStringUTFChars(name, NULL);
-    jobject ref = env->NewGlobalRef(function);
-    ALOGD_IF(DEBUG_JNI, "native_addCustomFunction %s ref: %p", nameStr, ref);
-    int err = sqlite3_create_function(handle, nameStr, numArgs, SQLITE_UTF8,
-            (void *)ref, custom_function_callback, NULL, NULL);
-    env->ReleaseStringUTFChars(name, nameStr);
-
-    if (err == SQLITE_OK)
-        return (int)ref;
-    else {
-        ALOGE("sqlite3_create_function returned %d", err);
-        env->DeleteGlobalRef(ref);
-        throw_sqlite3_exception(env, handle);
-        return 0;
-     }
-}
-
-static void native_releaseCustomFunction(JNIEnv* env, jobject object, jint ref)
-{
-    ALOGD_IF(DEBUG_JNI, "native_releaseCustomFunction %d", ref);
-    env->DeleteGlobalRef((jobject)ref);
-}
-
-static JNINativeMethod sMethods[] =
-{
-    /* name, signature, funcPtr */
-    {"dbopen", "(Ljava/lang/String;I)V", (void *)dbopen},
-    {"dbclose", "()V", (void *)dbclose},
-    {"enableSqlTracing", "(Ljava/lang/String;S)V", (void *)enableSqlTracing},
-    {"enableSqlProfiling", "(Ljava/lang/String;S)V", (void *)enableSqlProfiling},
-    {"native_setLocale", "(Ljava/lang/String;I)V", (void *)native_setLocale},
-    {"native_getDbLookaside", "()I", (void *)native_getDbLookaside},
-    {"native_setSqliteSoftHeapLimit", "(I)V", (void *)native_setSqliteSoftHeapLimit},
-    {"releaseMemory", "()I", (void *)native_releaseMemory},
-    {"native_finalize", "(I)V", (void *)native_finalize},
-    {"native_addCustomFunction",
-                    "(Ljava/lang/String;ILandroid/database/sqlite/SQLiteDatabase$CustomFunction;)I",
-                    (void *)native_addCustomFunction},
-    {"native_releaseCustomFunction", "(I)V", (void *)native_releaseCustomFunction},
-};
-
-int register_android_database_SQLiteDatabase(JNIEnv *env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/database/sqlite/SQLiteDatabase");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/database/sqlite/SQLiteDatabase\n");
-        return -1;
-    }
-
-    string_class = (jclass)env->NewGlobalRef(env->FindClass("java/lang/String"));
-    if (string_class == NULL) {
-        ALOGE("Can't find java/lang/String\n");
-        return -1;
-    }
-
-    offset_db_handle = env->GetFieldID(clazz, "mNativeHandle", "I");
-    if (offset_db_handle == NULL) {
-        ALOGE("Can't find SQLiteDatabase.mNativeHandle\n");
-        return -1;
-    }
-
-    clazz = env->FindClass("android/database/sqlite/SQLiteDatabase$CustomFunction");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/database/sqlite/SQLiteDatabase$CustomFunction\n");
-        return -1;
-    }
-    method_custom_function_callback = env->GetMethodID(clazz, "callback", "([Ljava/lang/String;)V");
-    if (method_custom_function_callback == NULL) {
-        ALOGE("Can't find method SQLiteDatabase.CustomFunction.callback\n");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteDatabase",
-            sMethods, NELEM(sMethods));
-}
-
-/* throw a SQLiteException with a message appropriate for the error in handle */
-void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle) {
-    throw_sqlite3_exception(env, handle, NULL);
-}
-
-/* throw a SQLiteException with the given message */
-void throw_sqlite3_exception(JNIEnv* env, const char* message) {
-    throw_sqlite3_exception(env, NULL, message);
-}
-
-/* throw a SQLiteException with a message appropriate for the error in handle
-   concatenated with the given message
- */
-void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message) {
-    if (handle) {
-        throw_sqlite3_exception(env, sqlite3_errcode(handle),
-                                sqlite3_errmsg(handle), message);
-    } else {
-        // we use SQLITE_OK so that a generic SQLiteException is thrown;
-        // any code not specified in the switch statement below would do.
-        throw_sqlite3_exception(env, SQLITE_OK, "unknown error", message);
-    }
-}
-
-/* throw a SQLiteException for a given error code */
-void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message) {
-    if (errcode == SQLITE_DONE) {
-        throw_sqlite3_exception(env, errcode, NULL, message);
-    } else {
-        char temp[21];
-        sprintf(temp, "error code %d", errcode);
-        throw_sqlite3_exception(env, errcode, temp, message);
-    }
-}
-
-/* throw a SQLiteException for a given error code, sqlite3message, and
-   user message
- */
-void throw_sqlite3_exception(JNIEnv* env, int errcode,
-                             const char* sqlite3Message, const char* message) {
-    const char* exceptionClass;
-    switch (errcode) {
-        case SQLITE_IOERR:
-            exceptionClass = "android/database/sqlite/SQLiteDiskIOException";
-            break;
-        case SQLITE_CORRUPT:
-        case SQLITE_NOTADB: // treat "unsupported file format" error as corruption also
-            exceptionClass = "android/database/sqlite/SQLiteDatabaseCorruptException";
-            break;
-        case SQLITE_CONSTRAINT:
-           exceptionClass = "android/database/sqlite/SQLiteConstraintException";
-           break;
-        case SQLITE_ABORT:
-           exceptionClass = "android/database/sqlite/SQLiteAbortException";
-           break;
-        case SQLITE_DONE:
-           exceptionClass = "android/database/sqlite/SQLiteDoneException";
-           break;
-        case SQLITE_FULL:
-           exceptionClass = "android/database/sqlite/SQLiteFullException";
-           break;
-        case SQLITE_MISUSE:
-           exceptionClass = "android/database/sqlite/SQLiteMisuseException";
-           break;
-        case SQLITE_PERM:
-           exceptionClass = "android/database/sqlite/SQLiteAccessPermException";
-           break;
-        case SQLITE_BUSY:
-           exceptionClass = "android/database/sqlite/SQLiteDatabaseLockedException";
-           break;
-        case SQLITE_LOCKED:
-           exceptionClass = "android/database/sqlite/SQLiteTableLockedException";
-           break;
-        case SQLITE_READONLY:
-           exceptionClass = "android/database/sqlite/SQLiteReadOnlyDatabaseException";
-           break;
-        case SQLITE_CANTOPEN:
-           exceptionClass = "android/database/sqlite/SQLiteCantOpenDatabaseException";
-           break;
-        case SQLITE_TOOBIG:
-           exceptionClass = "android/database/sqlite/SQLiteBlobTooBigException";
-           break;
-        case SQLITE_RANGE:
-           exceptionClass = "android/database/sqlite/SQLiteBindOrColumnIndexOutOfRangeException";
-           break;
-        case SQLITE_NOMEM:
-           exceptionClass = "android/database/sqlite/SQLiteOutOfMemoryException";
-           break;
-        case SQLITE_MISMATCH:
-           exceptionClass = "android/database/sqlite/SQLiteDatatypeMismatchException";
-           break;
-        case SQLITE_UNCLOSED:
-           exceptionClass = "android/database/sqlite/SQLiteUnfinalizedObjectsException";
-           break;
-        default:
-           exceptionClass = "android/database/sqlite/SQLiteException";
-           break;
-    }
-
-    if (sqlite3Message != NULL && message != NULL) {
-        char* fullMessage = (char *)malloc(strlen(sqlite3Message) + strlen(message) + 3);
-        if (fullMessage != NULL) {
-            strcpy(fullMessage, sqlite3Message);
-            strcat(fullMessage, ": ");
-            strcat(fullMessage, message);
-            jniThrowException(env, exceptionClass, fullMessage);
-            free(fullMessage);
-        } else {
-            jniThrowException(env, exceptionClass, sqlite3Message);
-        }
-    } else if (sqlite3Message != NULL) {
-        jniThrowException(env, exceptionClass, sqlite3Message);
-    } else {
-        jniThrowException(env, exceptionClass, message);
-    }
-}
-
-
-} // namespace android
diff --git a/core/jni/android_database_SQLiteGlobal.cpp b/core/jni/android_database_SQLiteGlobal.cpp
new file mode 100644
index 0000000..82cae5a
--- /dev/null
+++ b/core/jni/android_database_SQLiteGlobal.cpp
@@ -0,0 +1,78 @@
+/*
+ * 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.
+ */
+
+#define LOG_TAG "SQLiteGlobal"
+
+#include <jni.h>
+#include <JNIHelp.h>
+#include <android_runtime/AndroidRuntime.h>
+
+#include <sqlite3.h>
+#include <sqlite3_android.h>
+
+#include "android_database_SQLiteCommon.h"
+
+namespace android {
+
+// Called each time a message is logged.
+static void sqliteLogCallback(void* data, int iErrCode, const char* zMsg) {
+    bool verboseLog = !!data;
+    if (iErrCode == 0 || iErrCode == SQLITE_CONSTRAINT) {
+        if (verboseLog) {
+            ALOGV(LOG_VERBOSE, SQLITE_LOG_TAG, "(%d) %s\n", iErrCode, zMsg);
+        }
+    } else {
+        ALOG(LOG_ERROR, SQLITE_LOG_TAG, "(%d) %s\n", iErrCode, zMsg);
+    }
+}
+
+// Sets the global SQLite configuration.
+// This must be called before any other SQLite functions are called. */
+static void nativeConfig(JNIEnv* env, jclass clazz, jboolean verboseLog, jint softHeapLimit) {
+    // Enable multi-threaded mode.  In this mode, SQLite is safe to use by multiple
+    // threads as long as no two threads use the same database connection at the same
+    // time (which we guarantee in the SQLite database wrappers).
+    sqlite3_config(SQLITE_CONFIG_MULTITHREAD);
+
+    // Redirect SQLite log messages to the Android log.
+    sqlite3_config(SQLITE_CONFIG_LOG, &sqliteLogCallback, verboseLog ? (void*)1 : NULL);
+
+    // The soft heap limit prevents the page cache allocations from growing
+    // beyond the given limit, no matter what the max page cache sizes are
+    // set to. The limit does not, as of 3.5.0, affect any other allocations.
+    sqlite3_soft_heap_limit(softHeapLimit);
+}
+
+static jint nativeReleaseMemory(JNIEnv* env, jclass clazz, jint bytesToFree) {
+    return sqlite3_release_memory(bytesToFree);
+}
+
+static JNINativeMethod sMethods[] =
+{
+    /* name, signature, funcPtr */
+    { "nativeConfig", "(ZI)V",
+            (void*)nativeConfig },
+    { "nativeReleaseMemory", "(I)I",
+            (void*)nativeReleaseMemory },
+};
+
+int register_android_database_SQLiteGlobal(JNIEnv *env)
+{
+    return AndroidRuntime::registerNativeMethods(env, "android/database/sqlite/SQLiteGlobal",
+            sMethods, NELEM(sMethods));
+}
+
+} // namespace android
diff --git a/core/jni/android_database_SQLiteProgram.cpp b/core/jni/android_database_SQLiteProgram.cpp
deleted file mode 100644
index 2e34c00..0000000
--- a/core/jni/android_database_SQLiteProgram.cpp
+++ /dev/null
@@ -1,195 +0,0 @@
-/*
- * Copyright (C) 2006-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.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "Cursor"
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "sqlite3_exception.h"
-
-
-namespace android {
-
-static jfieldID gHandleField;
-static jfieldID gStatementField;
-
-
-#define GET_STATEMENT(env, object) \
-        (sqlite3_stmt *)env->GetIntField(object, gStatementField)
-#define GET_HANDLE(env, object) \
-        (sqlite3 *)env->GetIntField(object, gHandleField)
-
-static void native_compile(JNIEnv* env, jobject object, jstring sqlString)
-{
-    char buf[65];
-    strcpy(buf, "android_database_SQLiteProgram->native_compile() not implemented");
-    throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-    return;
-}
-
-static void native_bind_null(JNIEnv* env, jobject object,
-                             jint index)
-{
-    int err;
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-
-    err = sqlite3_bind_null(statement, index);
-    if (err != SQLITE_OK) {
-        char buf[32];
-        sprintf(buf, "handle %p", statement);
-        throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-        return;
-    }
-}
-
-static void native_bind_long(JNIEnv* env, jobject object,
-                             jint index, jlong value)
-{
-    int err;
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-
-    err = sqlite3_bind_int64(statement, index, value);
-    if (err != SQLITE_OK) {
-        char buf[32];
-        sprintf(buf, "handle %p", statement);
-        throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-        return;
-    }
-}
-
-static void native_bind_double(JNIEnv* env, jobject object,
-                             jint index, jdouble value)
-{
-    int err;
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-
-    err = sqlite3_bind_double(statement, index, value);
-    if (err != SQLITE_OK) {
-        char buf[32];
-        sprintf(buf, "handle %p", statement);
-        throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-        return;
-    }
-}
-
-static void native_bind_string(JNIEnv* env, jobject object,
-                               jint index, jstring sqlString)
-{
-    int err;
-    jchar const * sql;
-    jsize sqlLen;
-    sqlite3_stmt * statement= GET_STATEMENT(env, object);
-
-    sql = env->GetStringChars(sqlString, NULL);
-    sqlLen = env->GetStringLength(sqlString);
-    err = sqlite3_bind_text16(statement, index, sql, sqlLen * 2, SQLITE_TRANSIENT);
-    env->ReleaseStringChars(sqlString, sql);
-    if (err != SQLITE_OK) {
-        char buf[32];
-        sprintf(buf, "handle %p", statement);
-        throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-        return;
-    }
-}
-
-static void native_bind_blob(JNIEnv* env, jobject object,
-                               jint index, jbyteArray value)
-{
-    int err;
-    jchar const * sql;
-    jsize sqlLen;
-    sqlite3_stmt * statement= GET_STATEMENT(env, object);
-
-    jint len = env->GetArrayLength(value);
-    jbyte * bytes = env->GetByteArrayElements(value, NULL);
-
-    err = sqlite3_bind_blob(statement, index, bytes, len, SQLITE_TRANSIENT);
-    env->ReleaseByteArrayElements(value, bytes, JNI_ABORT);
-
-    if (err != SQLITE_OK) {
-        char buf[32];
-        sprintf(buf, "statement %p", statement);
-        throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-        return;
-    }
-}
-
-static void native_clear_bindings(JNIEnv* env, jobject object)
-{
-    int err;
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-
-    err = sqlite3_clear_bindings(statement);
-    if (err != SQLITE_OK) {
-        throw_sqlite3_exception(env, GET_HANDLE(env, object));
-        return;
-    }
-}
-
-static void native_finalize(JNIEnv* env, jobject object)
-{
-    char buf[66];
-    strcpy(buf, "android_database_SQLiteProgram->native_finalize() not implemented");
-    throw_sqlite3_exception(env, GET_HANDLE(env, object), buf);
-    return;
-}
-
-
-static JNINativeMethod sMethods[] =
-{
-     /* name, signature, funcPtr */
-    {"native_bind_null", "(I)V", (void *)native_bind_null},
-    {"native_bind_long", "(IJ)V", (void *)native_bind_long},
-    {"native_bind_double", "(ID)V", (void *)native_bind_double},
-    {"native_bind_string", "(ILjava/lang/String;)V", (void *)native_bind_string},
-    {"native_bind_blob", "(I[B)V", (void *)native_bind_blob},
-    {"native_clear_bindings", "()V", (void *)native_clear_bindings},
-};
-
-int register_android_database_SQLiteProgram(JNIEnv * env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/database/sqlite/SQLiteProgram");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/database/sqlite/SQLiteProgram");
-        return -1;
-    }
-
-    gHandleField = env->GetFieldID(clazz, "nHandle", "I");
-    gStatementField = env->GetFieldID(clazz, "nStatement", "I");
-
-    if (gHandleField == NULL || gStatementField == NULL) {
-        ALOGE("Error locating fields");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env,
-        "android/database/sqlite/SQLiteProgram", sMethods, NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/core/jni/android_database_SQLiteQuery.cpp b/core/jni/android_database_SQLiteQuery.cpp
deleted file mode 100644
index da7ccf0..0000000
--- a/core/jni/android_database_SQLiteQuery.cpp
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#undef LOG_TAG
-#define LOG_TAG "SqliteCursor.cpp"
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-
-#include <utils/Log.h>
-
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-
-#include "binder/CursorWindow.h"
-#include "sqlite3_exception.h"
-
-
-namespace android {
-
-enum CopyRowResult {
-    CPR_OK,
-    CPR_FULL,
-    CPR_ERROR,
-};
-
-static CopyRowResult copyRow(JNIEnv* env, CursorWindow* window,
-        sqlite3_stmt* statement, int numColumns, int startPos, int addedRows) {
-    // Allocate a new field directory for the row. This pointer is not reused
-    // since it may be possible for it to be relocated on a call to alloc() when
-    // the field data is being allocated.
-    status_t status = window->allocRow();
-    if (status) {
-        LOG_WINDOW("Failed allocating fieldDir at startPos %d row %d, error=%d",
-                startPos, addedRows, status);
-        return CPR_FULL;
-    }
-
-    // Pack the row into the window.
-    CopyRowResult result = CPR_OK;
-    for (int i = 0; i < numColumns; i++) {
-        int type = sqlite3_column_type(statement, i);
-        if (type == SQLITE_TEXT) {
-            // TEXT data
-            const char* text = reinterpret_cast<const char*>(
-                    sqlite3_column_text(statement, i));
-            // SQLite does not include the NULL terminator in size, but does
-            // ensure all strings are NULL terminated, so increase size by
-            // one to make sure we store the terminator.
-            size_t sizeIncludingNull = sqlite3_column_bytes(statement, i) + 1;
-            status = window->putString(addedRows, i, text, sizeIncludingNull);
-            if (status) {
-                LOG_WINDOW("Failed allocating %u bytes for text at %d,%d, error=%d",
-                        sizeIncludingNull, startPos + addedRows, i, status);
-                result = CPR_FULL;
-                break;
-            }
-            LOG_WINDOW("%d,%d is TEXT with %u bytes",
-                    startPos + addedRows, i, sizeIncludingNull);
-        } else if (type == SQLITE_INTEGER) {
-            // INTEGER data
-            int64_t value = sqlite3_column_int64(statement, i);
-            status = window->putLong(addedRows, i, value);
-            if (status) {
-                LOG_WINDOW("Failed allocating space for a long in column %d, error=%d",
-                        i, status);
-                result = CPR_FULL;
-                break;
-            }
-            LOG_WINDOW("%d,%d is INTEGER 0x%016llx", startPos + addedRows, i, value);
-        } else if (type == SQLITE_FLOAT) {
-            // FLOAT data
-            double value = sqlite3_column_double(statement, i);
-            status = window->putDouble(addedRows, i, value);
-            if (status) {
-                LOG_WINDOW("Failed allocating space for a double in column %d, error=%d",
-                        i, status);
-                result = CPR_FULL;
-                break;
-            }
-            LOG_WINDOW("%d,%d is FLOAT %lf", startPos + addedRows, i, value);
-        } else if (type == SQLITE_BLOB) {
-            // BLOB data
-            const void* blob = sqlite3_column_blob(statement, i);
-            size_t size = sqlite3_column_bytes(statement, i);
-            status = window->putBlob(addedRows, i, blob, size);
-            if (status) {
-                LOG_WINDOW("Failed allocating %u bytes for blob at %d,%d, error=%d",
-                        size, startPos + addedRows, i, status);
-                result = CPR_FULL;
-                break;
-            }
-            LOG_WINDOW("%d,%d is Blob with %u bytes",
-                    startPos + addedRows, i, size);
-        } else if (type == SQLITE_NULL) {
-            // NULL field
-            status = window->putNull(addedRows, i);
-            if (status) {
-                LOG_WINDOW("Failed allocating space for a null in column %d, error=%d",
-                        i, status);
-                result = CPR_FULL;
-                break;
-            }
-
-            LOG_WINDOW("%d,%d is NULL", startPos + addedRows, i);
-        } else {
-            // Unknown data
-            ALOGE("Unknown column type when filling database window");
-            throw_sqlite3_exception(env, "Unknown column type when filling window");
-            result = CPR_ERROR;
-            break;
-        }
-    }
-
-    // Free the last row if if was not successfully copied.
-    if (result != CPR_OK) {
-        window->freeLastRow();
-    }
-    return result;
-}
-
-static jlong nativeFillWindow(JNIEnv* env, jclass clazz, jint databasePtr,
-        jint statementPtr, jint windowPtr, jint offsetParam,
-        jint startPos, jint requiredPos, jboolean countAllRows) {
-    sqlite3* database = reinterpret_cast<sqlite3*>(databasePtr);
-    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
-    CursorWindow* window = reinterpret_cast<CursorWindow*>(windowPtr);
-
-    // Only do the binding if there is a valid offsetParam. If no binding needs to be done
-    // offsetParam will be set to 0, an invalid value.
-    if (offsetParam > 0) {
-        // Bind the offset parameter, telling the program which row to start with
-        // If an offset parameter is used, we cannot simply clear the window if it
-        // turns out that the requiredPos won't fit because the result set may
-        // depend on startPos, so we set startPos to requiredPos.
-        startPos = requiredPos;
-        int err = sqlite3_bind_int(statement, offsetParam, startPos);
-        if (err != SQLITE_OK) {
-            ALOGE("Unable to bind offset position, offsetParam = %d", offsetParam);
-            throw_sqlite3_exception(env, database);
-            return 0;
-        }
-        LOG_WINDOW("Bound offset position to startPos %d", startPos);
-    }
-
-    // We assume numRows is initially 0.
-    LOG_WINDOW("Window: numRows = %d, size = %d, freeSpace = %d",
-            window->getNumRows(), window->size(), window->freeSpace());
-
-    int numColumns = sqlite3_column_count(statement);
-    status_t status = window->setNumColumns(numColumns);
-    if (status) {
-        ALOGE("Failed to change column count from %d to %d", window->getNumColumns(), numColumns);
-        jniThrowException(env, "java/lang/IllegalStateException", "numColumns mismatch");
-        return 0;
-    }
-
-    int retryCount = 0;
-    int totalRows = 0;
-    int addedRows = 0;
-    bool windowFull = false;
-    bool gotException = false;
-    while (!gotException && (!windowFull || countAllRows)) {
-        int err = sqlite3_step(statement);
-        if (err == SQLITE_ROW) {
-            LOG_WINDOW("Stepped statement %p to row %d", statement, totalRows);
-            retryCount = 0;
-            totalRows += 1;
-
-            // Skip the row if the window is full or we haven't reached the start position yet.
-            if (startPos >= totalRows || windowFull) {
-                continue;
-            }
-
-            CopyRowResult cpr = copyRow(env, window, statement, numColumns, startPos, addedRows);
-            if (cpr == CPR_FULL && addedRows && startPos + addedRows < requiredPos) {
-                // We filled the window before we got to the one row that we really wanted.
-                // Clear the window and start filling it again from here.
-                // TODO: Would be nicer if we could progressively replace earlier rows.
-                window->clear();
-                window->setNumColumns(numColumns);
-                startPos += addedRows;
-                addedRows = 0;
-                cpr = copyRow(env, window, statement, numColumns, startPos, addedRows);
-            }
-
-            if (cpr == CPR_OK) {
-                addedRows += 1;
-            } else if (cpr == CPR_FULL) {
-                windowFull = true;
-            } else {
-                gotException = true;
-            }
-        } else if (err == SQLITE_DONE) {
-            // All rows processed, bail
-            LOG_WINDOW("Processed all rows");
-            break;
-        } else if (err == SQLITE_LOCKED || err == SQLITE_BUSY) {
-            // The table is locked, retry
-            LOG_WINDOW("Database locked, retrying");
-            if (retryCount > 50) {
-                ALOGE("Bailing on database busy retry");
-                throw_sqlite3_exception(env, database, "retrycount exceeded");
-                gotException = true;
-            } else {
-                // Sleep to give the thread holding the lock a chance to finish
-                usleep(1000);
-                retryCount++;
-            }
-        } else {
-            throw_sqlite3_exception(env, database);
-            gotException = true;
-        }
-    }
-
-    LOG_WINDOW("Resetting statement %p after fetching %d rows and adding %d rows"
-            "to the window in %d bytes",
-            statement, totalRows, addedRows, window->size() - window->freeSpace());
-    sqlite3_reset(statement);
-
-    // Report the total number of rows on request.
-    if (startPos > totalRows) {
-        ALOGE("startPos %d > actual rows %d", startPos, totalRows);
-    }
-    jlong result = jlong(startPos) << 32 | jlong(totalRows);
-    return result;
-}
-
-static jint nativeColumnCount(JNIEnv* env, jclass clazz, jint statementPtr) {
-    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
-    return sqlite3_column_count(statement);
-}
-
-static jstring nativeColumnName(JNIEnv* env, jclass clazz, jint statementPtr,
-        jint columnIndex) {
-    sqlite3_stmt* statement = reinterpret_cast<sqlite3_stmt*>(statementPtr);
-    const char* name = sqlite3_column_name(statement, columnIndex);
-    return env->NewStringUTF(name);
-}
-
-
-static JNINativeMethod sMethods[] =
-{
-     /* name, signature, funcPtr */
-    { "nativeFillWindow", "(IIIIIIZ)J",
-            (void*)nativeFillWindow },
-    { "nativeColumnCount", "(I)I",
-            (void*)nativeColumnCount},
-    { "nativeColumnName", "(II)Ljava/lang/String;",
-            (void*)nativeColumnName},
-};
-
-int register_android_database_SQLiteQuery(JNIEnv * env)
-{
-    return AndroidRuntime::registerNativeMethods(env,
-        "android/database/sqlite/SQLiteQuery", sMethods, NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/core/jni/android_database_SQLiteStatement.cpp b/core/jni/android_database_SQLiteStatement.cpp
deleted file mode 100644
index e376258..0000000
--- a/core/jni/android_database_SQLiteStatement.cpp
+++ /dev/null
@@ -1,286 +0,0 @@
-/* //device/libs/android_runtime/android_database_SQLiteCursor.cpp
-**
-** Copyright 2006, The Android Open Source Project
-**
-** Licensed under the Apache License, Version 2.0 (the "License");
-** you may not use this file except in compliance with the License.
-** You may obtain a copy of the License at
-**
-**     http://www.apache.org/licenses/LICENSE-2.0
-**
-** Unless required by applicable law or agreed to in writing, software
-** distributed under the License is distributed on an "AS IS" BASIS,
-** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-** See the License for the specific language governing permissions and
-** limitations under the License.
-*/
-
-#undef LOG_TAG
-#define LOG_TAG "SQLiteStatementCpp"
-
-#include "android_util_Binder.h"
-
-#include <jni.h>
-#include <JNIHelp.h>
-#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-
-#include <cutils/ashmem.h>
-#include <utils/Log.h>
-
-#include <fcntl.h>
-#include <stdio.h>
-#include <string.h>
-#include <unistd.h>
-#include <sys/mman.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-
-#include "sqlite3_exception.h"
-
-namespace android {
-
-
-sqlite3_stmt * compile(JNIEnv* env, jobject object,
-                       sqlite3 * handle, jstring sqlString);
-
-static jfieldID gHandleField;
-static jfieldID gStatementField;
-
-
-#define GET_STATEMENT(env, object) \
-        (sqlite3_stmt *)env->GetIntField(object, gStatementField)
-#define GET_HANDLE(env, object) \
-        (sqlite3 *)env->GetIntField(object, gHandleField)
-
-
-static jint native_execute(JNIEnv* env, jobject object)
-{
-    int err;
-    sqlite3 * handle = GET_HANDLE(env, object);
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-    int numChanges = -1;
-
-    // Execute the statement
-    err = sqlite3_step(statement);
-
-    // Throw an exception if an error occurred
-    if (err == SQLITE_ROW) {
-        throw_sqlite3_exception(env,
-                "Queries can be performed using SQLiteDatabase query or rawQuery methods only.");
-    } else if (err != SQLITE_DONE) {
-        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
-    } else {
-        numChanges = sqlite3_changes(handle);
-    }
-
-    // Reset the statement so it's ready to use again
-    sqlite3_reset(statement);
-    return numChanges;
-}
-
-static jlong native_executeInsert(JNIEnv* env, jobject object)
-{
-    sqlite3 * handle = GET_HANDLE(env, object);
-    jint numChanges = native_execute(env, object);
-    if (numChanges > 0) {
-        return sqlite3_last_insert_rowid(handle);
-    } else {
-        return -1;
-    }
-}
-
-static jlong native_1x1_long(JNIEnv* env, jobject object)
-{
-    int err;
-    sqlite3 * handle = GET_HANDLE(env, object);
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-    jlong value = -1;
-
-    // Execute the statement
-    err = sqlite3_step(statement);
-
-    // Handle the result
-    if (err == SQLITE_ROW) {
-        // No errors, read the data and return it
-        value = sqlite3_column_int64(statement, 0);
-    } else {
-        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
-    }
-
-    // Reset the statment so it's ready to use again
-    sqlite3_reset(statement);
-
-    return value;
-}
-
-static jstring native_1x1_string(JNIEnv* env, jobject object)
-{
-    int err;
-    sqlite3 * handle = GET_HANDLE(env, object);
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-    jstring value = NULL;
-
-    // Execute the statement
-    err = sqlite3_step(statement);
-
-    // Handle the result
-    if (err == SQLITE_ROW) {
-        // No errors, read the data and return it
-        char const * text = (char const *)sqlite3_column_text(statement, 0);
-        value = env->NewStringUTF(text);
-    } else {
-        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
-    }
-
-    // Reset the statment so it's ready to use again
-    sqlite3_reset(statement);
-
-    return value;
-}
-
-static jobject createParcelFileDescriptor(JNIEnv * env, int fd)
-{
-    // Create FileDescriptor object
-    jobject fileDesc = jniCreateFileDescriptor(env, fd);
-    if (fileDesc == NULL) {
-        // FileDescriptor constructor has thrown an exception
-        close(fd);
-        return NULL;
-    }
-
-    // Wrap it in a ParcelFileDescriptor
-    jobject parcelFileDesc = newParcelFileDescriptor(env, fileDesc);
-    if (parcelFileDesc == NULL) {
-        // ParcelFileDescriptor constructor has thrown an exception
-        close(fd);
-        return NULL;
-    }
-
-    return parcelFileDesc;
-}
-
-// Creates an ashmem area, copies some data into it, and returns
-// a ParcelFileDescriptor for the ashmem area.
-static jobject create_ashmem_region_with_data(JNIEnv * env,
-                                              const void * data, int length)
-{
-    // Create ashmem area
-    int fd = ashmem_create_region(NULL, length);
-    if (fd < 0) {
-        ALOGE("ashmem_create_region failed: %s", strerror(errno));
-        jniThrowIOException(env, errno);
-        return NULL;
-    }
-
-    if (length > 0) {
-        // mmap the ashmem area
-        void * ashmem_ptr =
-                mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
-        if (ashmem_ptr == MAP_FAILED) {
-            ALOGE("mmap failed: %s", strerror(errno));
-            jniThrowIOException(env, errno);
-            close(fd);
-            return NULL;
-        }
-
-        // Copy data to ashmem area
-        memcpy(ashmem_ptr, data, length);
-
-        // munmap ashmem area
-        if (munmap(ashmem_ptr, length) < 0) {
-            ALOGE("munmap failed: %s", strerror(errno));
-            jniThrowIOException(env, errno);
-            close(fd);
-            return NULL;
-        }
-    }
-
-    // Make ashmem area read-only
-    if (ashmem_set_prot_region(fd, PROT_READ) < 0) {
-        ALOGE("ashmem_set_prot_region failed: %s", strerror(errno));
-        jniThrowIOException(env, errno);
-        close(fd);
-        return NULL;
-    }
-
-    // Wrap it in a ParcelFileDescriptor
-    return createParcelFileDescriptor(env, fd);
-}
-
-static jobject native_1x1_blob_ashmem(JNIEnv* env, jobject object)
-{
-    int err;
-    sqlite3 * handle = GET_HANDLE(env, object);
-    sqlite3_stmt * statement = GET_STATEMENT(env, object);
-    jobject value = NULL;
-
-    // Execute the statement
-    err = sqlite3_step(statement);
-
-    // Handle the result
-    if (err == SQLITE_ROW) {
-        // No errors, read the data and return it
-        const void * blob = sqlite3_column_blob(statement, 0);
-        if (blob != NULL) {
-            int len = sqlite3_column_bytes(statement, 0);
-            if (len >= 0) {
-                value = create_ashmem_region_with_data(env, blob, len);
-            }
-        }
-    } else {
-        throw_sqlite3_exception_errcode(env, err, sqlite3_errmsg(handle));
-    }
-
-    // Reset the statment so it's ready to use again
-    sqlite3_reset(statement);
-
-    return value;
-}
-
-static void native_executeSql(JNIEnv* env, jobject object, jstring sql)
-{
-    char const* sqlString = env->GetStringUTFChars(sql, NULL);
-    sqlite3 * handle = GET_HANDLE(env, object);
-    int err = sqlite3_exec(handle, sqlString, NULL, NULL, NULL);
-    if (err != SQLITE_OK) {
-        throw_sqlite3_exception(env, handle);
-    }
-    env->ReleaseStringUTFChars(sql, sqlString);
-}
-
-static JNINativeMethod sMethods[] =
-{
-     /* name, signature, funcPtr */
-    {"native_execute", "()I", (void *)native_execute},
-    {"native_executeInsert", "()J", (void *)native_executeInsert},
-    {"native_1x1_long", "()J", (void *)native_1x1_long},
-    {"native_1x1_string", "()Ljava/lang/String;", (void *)native_1x1_string},
-    {"native_1x1_blob_ashmem", "()Landroid/os/ParcelFileDescriptor;", (void *)native_1x1_blob_ashmem},
-    {"native_executeSql", "(Ljava/lang/String;)V", (void *)native_executeSql},
-};
-
-int register_android_database_SQLiteStatement(JNIEnv * env)
-{
-    jclass clazz;
-
-    clazz = env->FindClass("android/database/sqlite/SQLiteStatement");
-    if (clazz == NULL) {
-        ALOGE("Can't find android/database/sqlite/SQLiteStatement");
-        return -1;
-    }
-
-    gHandleField = env->GetFieldID(clazz, "nHandle", "I");
-    gStatementField = env->GetFieldID(clazz, "nStatement", "I");
-
-    if (gHandleField == NULL || gStatementField == NULL) {
-        ALOGE("Error locating fields");
-        return -1;
-    }
-
-    return AndroidRuntime::registerNativeMethods(env,
-        "android/database/sqlite/SQLiteStatement", sMethods, NELEM(sMethods));
-}
-
-} // namespace android
diff --git a/core/jni/sqlite3_exception.h b/core/jni/sqlite3_exception.h
deleted file mode 100644
index 13735a1..0000000
--- a/core/jni/sqlite3_exception.h
+++ /dev/null
@@ -1,47 +0,0 @@
-/* //device/libs/include/android_runtime/sqlite3_exception.h
-**
-** Copyright 2007, 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.
-*/
-
-#ifndef _SQLITE3_EXCEPTION_H
-#define _SQLITE3_EXCEPTION_H 1
-
-#include <jni.h>
-#include <JNIHelp.h>
-//#include <android_runtime/AndroidRuntime.h>
-
-#include <sqlite3.h>
-
-namespace android {
-
-/* throw a SQLiteException with a message appropriate for the error in handle */
-void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle);
-
-/* throw a SQLiteException with the given message */
-void throw_sqlite3_exception(JNIEnv* env, const char* message);
-
-/* throw a SQLiteException with a message appropriate for the error in handle
-   concatenated with the given message
- */
-void throw_sqlite3_exception(JNIEnv* env, sqlite3* handle, const char* message);
-
-/* throw a SQLiteException for a given error code */
-void throw_sqlite3_exception_errcode(JNIEnv* env, int errcode, const char* message);
-
-void throw_sqlite3_exception(JNIEnv* env, int errcode,
-                             const char* sqlite3Message, const char* message);
-}
-
-#endif // _SQLITE3_EXCEPTION_H
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index fea8523..71e3575 100755
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1816,11 +1816,10 @@
         <attr name="scrollbarAlwaysDrawVerticalTrack" format="boolean" />
 
         <!-- {@deprecated This attribute is deprecated and will be ignored as of
-             API level {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH}.
+             API level 14 (<code>android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH</code>).
              Using fading edges may introduce noticeable performance
              degradations and should be used only when required by the application's
-             visual design. To request fading edges with API level
-             {@link android.os.Build.VERSION_CODES#ICE_CREAM_SANDWICH} and above,
+             visual design. To request fading edges with API level 14 and above,
              use the <code>requiresFadingEdge</code> attribute instead.} -->
         <attr name="fadingEdge">
             <!-- No edge is faded. -->
diff --git a/core/tests/coretests/src/android/database/CursorWindowTest.java b/core/tests/coretests/src/android/database/CursorWindowTest.java
index 8c8081c..075f5b7 100644
--- a/core/tests/coretests/src/android/database/CursorWindowTest.java
+++ b/core/tests/coretests/src/android/database/CursorWindowTest.java
@@ -35,15 +35,45 @@
     }
 
     @SmallTest
-    public void testValuesLocalWindow() {
-        doTestValues(new CursorWindow(true));
+    public void testConstructor_WithName() {
+        CursorWindow window = new CursorWindow("MyWindow");
+        assertEquals("MyWindow", window.getName());
+        assertEquals(0, window.getStartPosition());
+        window.close();
     }
-    
+
     @SmallTest
-    public void testValuesRemoteWindow() {
-        doTestValues(new CursorWindow(false));
+    public void testConstructorWithEmptyName() {
+        CursorWindow window = new CursorWindow("");
+        assertEquals("<unnamed>", window.getName());
+        assertEquals(0, window.getStartPosition());
+        window.close();
     }
-    
+
+    @SmallTest
+    public void testConstructorWithNullName() {
+        CursorWindow window = new CursorWindow(null);
+        assertEquals("<unnamed>", window.getName());
+        assertEquals(0, window.getStartPosition());
+        window.close();
+    }
+
+    @SmallTest
+    public void testDeprecatedConstructor() {
+        @SuppressWarnings("deprecation")
+        CursorWindow window = new CursorWindow(true /*this argument is ignored*/);
+        assertEquals("<unnamed>", window.getName());
+        assertEquals(0, window.getStartPosition());
+        window.close();
+    }
+
+    @SmallTest
+    public void testValues() {
+        CursorWindow window = new CursorWindow("MyWindow");
+        doTestValues(window);
+        window.close();
+    }
+
     private void doTestValues(CursorWindow window) {
         assertTrue(window.setNumColumns(7));
         assertTrue(window.allocRow());
diff --git a/core/tests/coretests/src/android/database/DatabaseCursorTest.java b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
index 179338d..36f0f4b 100644
--- a/core/tests/coretests/src/android/database/DatabaseCursorTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseCursorTest.java
@@ -16,7 +16,6 @@
 
 package android.database;
 
-import dalvik.annotation.BrokenTest;
 import android.content.ContentValues;
 import android.content.Context;
 import android.database.Cursor;
@@ -27,13 +26,11 @@
 import android.database.sqlite.SQLiteCursorDriver;
 import android.database.sqlite.SQLiteDatabase;
 import android.database.sqlite.SQLiteQuery;
-import android.database.sqlite.SQLiteStatement;
 import android.os.Looper;
 import android.test.AndroidTestCase;
 import android.test.PerformanceTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
 import java.io.File;
diff --git a/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java b/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java
index 1cfd960..91c7687 100644
--- a/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseErrorHandlerTest.java
@@ -21,7 +21,6 @@
 import android.database.sqlite.SQLiteDiskIOException;
 import android.database.sqlite.SQLiteException;
 import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 
 import java.io.BufferedWriter;
diff --git a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
index 6786700..c7cb43d 100644
--- a/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseGeneralTest.java
@@ -410,40 +410,6 @@
         }
     }
 
-    private class ChangeObserver extends ContentObserver {
-        private int mCursorNotificationCount = 0;
-        private int mNotificationCount = 0;
-
-        public int getCursorNotificationCount() {
-            return mCursorNotificationCount;
-        }
-
-        public int getNotificationCount() {
-            return mNotificationCount;
-        }
-
-        public ChangeObserver(boolean cursor) {
-            super(new Handler());
-            mCursor = cursor;
-        }
-
-        @Override
-        public boolean deliverSelfNotifications() {
-            return true;
-        }
-
-        @Override
-        public void onChange(boolean selfChange) {
-            if (mCursor) {
-                mCursorNotificationCount++;
-            } else {
-                mNotificationCount++;
-            }
-        }
-
-        boolean mCursor;
-    }
-
     @MediumTest
     public void testSelectionArgs() throws Exception {
         mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, data TEXT);");
diff --git a/core/tests/coretests/src/android/database/DatabaseLockTest.java b/core/tests/coretests/src/android/database/DatabaseLockTest.java
index f7a9f8a..8d3cf5a 100644
--- a/core/tests/coretests/src/android/database/DatabaseLockTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseLockTest.java
@@ -16,18 +16,13 @@
 
 package android.database;
 
-import android.app.Activity;
-import android.content.Context;
 import android.database.sqlite.SQLiteDatabase;
-import android.test.suitebuilder.annotation.LargeTest;
 import android.test.suitebuilder.annotation.Suppress;
 import android.util.Log;
 import java.io.File;
 import java.util.concurrent.atomic.AtomicInteger;
 import android.test.AndroidTestCase;
 
-import junit.framework.TestCase;
-
 /* 
  * This is a series of unit tests for database locks.
  *
@@ -104,9 +99,9 @@
         public void run() {
             for (int i = 0; i < NUM_ITERATIONS; i++) {
                 mDatabase.beginTransaction();
-                int val = mCounter.incrementAndGet();
+                mCounter.incrementAndGet();
                 try {
-                    Thread.currentThread().sleep(SLEEP_TIME);
+                    Thread.sleep(SLEEP_TIME);
                 } catch (InterruptedException e) {
                     // ignore
                 }
@@ -124,7 +119,6 @@
     @Suppress
     public void testLockLatency() {
         startDatabaseLatencyThread();
-        int previous = 0;
         long sumTime = 0;
         long maxTime = 0;
         for (int i = 0; i < NUM_ITERATIONS; i++) { 
@@ -137,7 +131,7 @@
             }
             sumTime += elapsedTime;
             try {
-                Thread.currentThread().sleep(SLEEP_TIME); 
+                Thread.sleep(SLEEP_TIME); 
             } catch (InterruptedException e) {
                 // ignore
             }   
@@ -164,7 +158,7 @@
             {
                 mDatabase.beginTransaction();
                 try {
-                    Thread.currentThread().sleep(SLEEP_TIME);
+                    Thread.sleep(SLEEP_TIME);
                 } catch (InterruptedException e) {
                     // ignore
                 } 
diff --git a/core/tests/coretests/src/android/database/DatabasePerformanceTests.java b/core/tests/coretests/src/android/database/DatabasePerformanceTests.java
index b8ebcc4..d0e739b 100644
--- a/core/tests/coretests/src/android/database/DatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/DatabasePerformanceTests.java
@@ -35,6 +35,7 @@
  * 
  */
 
+@SuppressWarnings("deprecation")
 public class DatabasePerformanceTests {
 
     public static String[] children() {
diff --git a/core/tests/coretests/src/android/database/DatabaseStatementTest.java b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
index 71dc3ae..512d5cd 100644
--- a/core/tests/coretests/src/android/database/DatabaseStatementTest.java
+++ b/core/tests/coretests/src/android/database/DatabaseStatementTest.java
@@ -25,8 +25,6 @@
 import android.test.AndroidTestCase;
 import android.test.PerformanceTestCase;
 import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import junit.framework.TestCase;
 
 import java.io.File;
 
diff --git a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
index 0dca90b..adf88d2 100644
--- a/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
+++ b/core/tests/coretests/src/android/database/NewDatabasePerformanceTests.java
@@ -20,7 +20,6 @@
 import android.database.sqlite.SQLiteDatabase;
 import android.test.PerformanceTestCase;
 
-import junit.framework.Assert;
 import junit.framework.TestCase;
 
 import java.io.File;
@@ -33,1202 +32,1196 @@
 
 public class NewDatabasePerformanceTests {
 
-  // Edit this to change the test run times.  The original is 100.
-  final static int kMultiplier = 1;
-  
-  public static class PerformanceBase extends TestCase
-          implements PerformanceTestCase {
-    protected static final int CURRENT_DATABASE_VERSION = 42;
-    protected SQLiteDatabase mDatabase;
-    protected File mDatabaseFile;
+    // Edit this to change the test run times.  The original is 100.
+    final static int kMultiplier = 1;
 
-    public void setUp() {
-      mDatabaseFile = new File("/sdcard", "perf_database_test.db");
-      if (mDatabaseFile.exists()) {
-        mDatabaseFile.delete();
-      }
-      mDatabase =
-        SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(),
-            null);
-      assertTrue(mDatabase != null);
-      mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+    public static class PerformanceBase extends TestCase
+    implements PerformanceTestCase {
+        protected static final int CURRENT_DATABASE_VERSION = 42;
+        protected SQLiteDatabase mDatabase;
+        protected File mDatabaseFile;
+
+        public void setUp() {
+            mDatabaseFile = new File("/sdcard", "perf_database_test.db");
+            if (mDatabaseFile.exists()) {
+                mDatabaseFile.delete();
+            }
+            mDatabase =
+                    SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(),
+                            null);
+            assertTrue(mDatabase != null);
+            mDatabase.setVersion(CURRENT_DATABASE_VERSION);
+        }
+
+        public void tearDown() {
+            mDatabase.close();
+            mDatabaseFile.delete();
+        }
+
+        public boolean isPerformanceOnly() {
+            return true;
+        }
+
+        // These tests can only be run once.
+        public int startPerformance(Intermediates intermediates) {
+            return 0;
+        }
+
+        public String numberName(int number) {
+            String result = "";
+
+            if (number >= 1000) {
+                result += numberName((number / 1000)) + " thousand";
+                number = (number % 1000);
+
+                if (number > 0) result += " ";
+            }
+
+            if (number >= 100) {
+                result += ONES[(number / 100)] + " hundred";
+                number = (number % 100);
+
+                if (number > 0) result += " ";
+            }
+
+            if (number >= 20) {
+                result += TENS[(number / 10)];
+                number = (number % 10);
+
+                if (number > 0) result += " ";
+            }
+
+            if (number > 0) {
+                result += ONES[number];
+            }
+
+            return result;
+        }
     }
 
-    public void tearDown() {
-      mDatabase.close();
-      mDatabaseFile.delete();
+    /**
+     * Test 1000 inserts.
+     */
+
+    public static class Insert1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+
+        private String[] statements = new String[SIZE];
+
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                statements[i] =
+                        "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                                + numberName(r) + "')";
+            }
+
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.execSQL(statements[i]);
+            }
+        }
     }
 
-    public boolean isPerformanceOnly() {
-      return true;
+    /**
+     * Test 1000 inserts into an indexed table.
+     */
+
+    public static class InsertIndexed1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+
+        private String[] statements = new String[SIZE];
+
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                statements[i] =
+                        "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                                + numberName(r) + "')";
+            }
+
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.execSQL(statements[i]);
+            }
+        }
     }
 
-    // These tests can only be run once.
-    public int startPerformance(Intermediates intermediates) {
-      return 0;
+    /**
+     * 100 SELECTs without an index
+     */
+
+    public static class Select100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
+
+        private String[] where = new String[SIZE];
+
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
+
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+
+            for (int i = 0; i < SIZE; i++) {
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public String numberName(int number) {
-      String result = "";
+    /**
+     * 100 SELECTs on a string comparison
+     */
 
-      if (number >= 1000) {
-        result += numberName((number / 1000)) + " thousand";
-        number = (number % 1000);
+    public static class SelectStringComparison100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-        if (number > 0) result += " ";
-      }
+        private String[] where = new String[SIZE];
 
-      if (number >= 100) {
-        result += ONES[(number / 100)] + " hundred";
-        number = (number % 100);
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-        if (number > 0) result += " ";
-      }
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      if (number >= 20) {
-        result += TENS[(number / 10)];
-        number = (number % 10);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-        if (number > 0) result += " ";
-      }
+            for (int i = 0; i < SIZE; i++) {
+                where[i] = "c LIKE '" + numberName(i) + "'";
+            }
+        }
 
-      if (number > 0) {
-        result += ONES[number];
-      }
-
-      return result;
-    }
-  }
-
-  /**
-   * Test 1000 inserts.
-   */
-
-  public static class Insert1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-
-    private String[] statements = new String[SIZE];
-
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        statements[i] =
-          "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-          + numberName(r) + "')";
-      }
-
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.execSQL(statements[i]);
-      }
-    }
-  }
+    /**
+     * 100 SELECTs with an index
+     */
 
-  /**
-   * Test 1000 inserts into an indexed table.
-   */
+    public static class SelectIndex100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-  public static class InsertIndexed1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
+        private String[] where = new String[SIZE];
 
-    private String[] statements = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        statements[i] =
-          "INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-          + numberName(r) + "')";
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
+            for (int i = 0; i < SIZE; i++) {
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.execSQL(statements[i]);
-      }
-    }
-  }
+    /**
+     *  INNER JOIN without an index
+     */
 
-  /**
-   * 100 SELECTs without an index
-   */
+    public static class InnerJoin100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"t1.a"};
 
-  public static class Select100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"count(*)", "avg(b)"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-      }
+        public void testRun() {
+            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                    null, null, null, null);
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  INNER JOIN without an index on one side
+     */
 
-  /**
-   * 100 SELECTs on a string comparison
-   */
+    public static class InnerJoinOneSide100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"t1.a"};
 
-  public static class SelectStringComparison100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"count(*)", "avg(b)"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        where[i] = "c LIKE '" + numberName(i) + "'";
-      }
+        public void testRun() {
+            mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
+                    null, null, null, null);
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  INNER JOIN without an index on one side
+     */
 
-  /**
-   * 100 SELECTs with an index
-   */
+    public static class InnerJoinNoIndex100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"t1.a"};
 
-  public static class SelectIndex100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"count(*)", "avg(b)"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-      }
+        public void testRun() {
+            mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
+                    null, null, null, null);
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  100 SELECTs with subqueries. Subquery is using an index
+     */
 
-  /**
-   *  INNER JOIN without an index
-   */
+    public static class SelectSubQIndex100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"t1.a"};
 
-  public static class InnerJoin100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"t1.a"};
+        private String[] where = new String[SIZE];
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase
-      .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            mDatabase.execSQL("CREATE INDEX i2b ON t2(b)");
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
+
+            for (int i = 0; i < SIZE; i++) {
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] =
+                        "t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower
+                        + " AND t2.b < " + upper + ")";
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-          null, null, null, null);
-    }
-  }
+    /**
+     *  100 SELECTs on string comparison with Index
+     */
 
-  /**
-   *  INNER JOIN without an index on one side
-   */
+    public static class SelectIndexStringComparison100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"count(*)", "avg(b)"};
 
-  public static class InnerJoinOneSide100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"t1.a"};
+        private String[] where = new String[SIZE];
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase
-      .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
 
-      mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                where[i] = "c LIKE '" + numberName(i) + "'";
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      mDatabase.query("t1 INNER JOIN t2 ON t1.b = t2.b", COLUMNS, null,
-          null, null, null, null);
-    }
-  }
+    /**
+     *  100 SELECTs on integer
+     */
 
-  /**
-   *  INNER JOIN without an index on one side
-   */
+    public static class SelectInteger100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"b"};
 
-  public static class InnerJoinNoIndex100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"t1.a"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase
-      .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      mDatabase.query("t1 INNER JOIN t2 ON t1.c = t2.c", COLUMNS, null,
-          null, null, null, null);
-    }
-  }
+    /**
+     *  100 SELECTs on String
+     */
 
-  /**
-   *  100 SELECTs with subqueries. Subquery is using an index
-   */
+    public static class SelectString100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"c"};
 
-  public static class SelectSubQIndex100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"t1.a"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase
-      .execSQL("CREATE TABLE t2(a INTEGER, b INTEGER, c VARCHAR(100))");
+        }
 
-      mDatabase.execSQL("CREATE INDEX i2b ON t2(b)");
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t2 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] =
-          "t1.b IN (SELECT t2.b FROM t2 WHERE t2.b >= " + lower
-          + " AND t2.b < " + upper + ")";
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  100 SELECTs on integer with index
+     */
 
-  /**
-   *  100 SELECTs on string comparison with Index
-   */
+    public static class SelectIntegerIndex100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"b"};
 
-  public static class SelectIndexStringComparison100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"count(*)", "avg(b)"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1b on t1(b)");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        where[i] = "c LIKE '" + numberName(i) + "'";
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  100 SELECTs on String with index
+     */
 
-  /**
-   *  100 SELECTs on integer 
-   */
+    public static class SelectIndexString100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"c"};
 
-  public static class SelectInteger100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"b"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t1", COLUMNS, null, null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  100 SELECTs on String with starts with
+     */
 
-  /**
-   *  100 SELECTs on String
-   */
+    public static class SelectStringStartsWith100 extends PerformanceBase {
+        private static final int SIZE = 1 * kMultiplier;
+        private static final String[] COLUMNS = {"c"};
+        private String[] where = new String[SIZE];
 
-  public static class SelectString100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"c"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    private String[] where = new String[SIZE];
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            }
 
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase
+                .query("t1", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  1000 Deletes on an indexed table
+     */
 
-  /**
-   *  100 SELECTs on integer with index
-   */
+    public static class DeleteIndexed1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
 
-  public static class SelectIntegerIndex100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"b"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1b on t1(b)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+        }
 
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.delete("t1", null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  1000 Deletes
+     */
 
-  /**
-   *  100 SELECTs on String with index
-   */
+    public static class Delete1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
 
-  public static class SelectIndexString100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"c"};      
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+        }
 
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.delete("t1", null, null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t1", COLUMNS, null, null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  1000 DELETE's without an index with where clause
+     */
 
-  /**
-   *  100 SELECTs on String with starts with
-   */
+    public static class DeleteWhere1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+        private String[] where = new String[SIZE];
 
-  public static class SelectStringStartsWith100 extends PerformanceBase {
-    private static final int SIZE = 1 * kMultiplier;
-    private static final String[] COLUMNS = {"c"};
-    private String[] where = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1c ON t1(c)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        where[i] = "c LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-      }
-
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.delete("t1", where[i], null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase
-        .query("t1", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
+    /**
+     *  1000 DELETE's with an index with where clause
+     */
 
-  /**
-   *  1000 Deletes on an indexed table
-   */
+    public static class DeleteIndexWhere1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+        private String[] where = new String[SIZE];
 
-  public static class DeleteIndexed1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-    private static final String[] COLUMNS = {"c"};
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i3c ON t1(c)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+            }
+        }
 
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.delete("t1", where[i], null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.delete("t1", null, null);
-      }
-    }
-  }
+    /**
+     *  1000 update's with an index with where clause
+     */
 
-  /**
-   *  1000 Deletes
-   */
+    public static class UpdateIndexWhere1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+        private String[] where = new String[SIZE];
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class Delete1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-    private static final String[] COLUMNS = {"c"};       
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
 
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+                ContentValues b = new ContentValues(1);
+                b.put("b", upper);
+                mValues[i] = b;
+
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.update("t1", mValues[i], where[i], null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.delete("t1", null, null);
-      }
-    }
-  }
+    /**
+     *  1000 update's without an index with where clause
+     */
 
-  /**
-   *  1000 DELETE's without an index with where clause 
-   */
+    public static class UpdateWhere1000 extends PerformanceBase {
+        private static final int SIZE = 10 * kMultiplier;
+        private String[] where = new String[SIZE];
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class DeleteWhere1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-    private String[] where = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
 
-      for (int i = 0; i < SIZE; i++) {
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-      }
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "b >= " + lower + " AND b < " + upper;
+                ContentValues b = new ContentValues(1);
+                b.put("b", upper);
+                mValues[i] = b;
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.update("t1", mValues[i], where[i], null);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.delete("t1", where[i], null);
-      }
-    }
-  }
+    /**
+     *  10000 inserts for an integer
+     */
 
-  /**
-   *  1000 DELETE's with an index with where clause 
-   */
+    public static class InsertInteger10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class DeleteIndexWhere1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-    private String[] where = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                ContentValues b = new ContentValues(1);
+                b.put("a", r);
+                mValues[i] = b;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.insert("t1", null, mValues[i]);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.delete("t1", where[i], null);
-      }
-    }
-  }
+    /**
+     *  10000 inserts for an integer -indexed table
+     */
 
-  /**
-   *  1000 update's with an index with where clause 
-   */
+    public static class InsertIntegerIndex10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class UpdateIndexWhere1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;
-    private String[] where = new String[SIZE];
-    ContentValues[] mValues = new ContentValues[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a INTEGER)");
+            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1b ON t1(b)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                ContentValues b = new ContentValues(1);
+                b.put("a", r);
+                mValues[i] = b;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-        ContentValues b = new ContentValues(1);
-        b.put("b", upper);
-        mValues[i] = b;
-
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.insert("t1", null, mValues[i]);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.update("t1", mValues[i], where[i], null);
-      }
-    }
-  }
+    /**
+     *  10000 inserts for a String
+     */
 
-  /**
-   *  1000 update's without an index with where clause 
-   */
+    public static class InsertString10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class UpdateWhere1000 extends PerformanceBase {
-    private static final int SIZE = 10 * kMultiplier;       
-    private String[] where = new String[SIZE];
-    ContentValues[] mValues = new ContentValues[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER, b INTEGER, c VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                ContentValues b = new ContentValues(1);
+                b.put("a", numberName(r));
+                mValues[i] = b;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t1 VALUES(" + i + "," + r + ",'"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "b >= " + lower + " AND b < " + upper;
-        ContentValues b = new ContentValues(1);
-        b.put("b", upper);
-        mValues[i] = b;
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.insert("t1", null, mValues[i]);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.update("t1", mValues[i], where[i], null);
-      }
-    }
-  }
+    /**
+     *  10000 inserts for a String - indexed table
+     */
 
-  /**
-   *  10000 inserts for an integer 
-   */
+    public static class InsertStringIndexed10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        ContentValues[] mValues = new ContentValues[SIZE];
 
-  public static class InsertInteger10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    ContentValues[] mValues = new ContentValues[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t1(a VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER)");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                ContentValues b = new ContentValues(1);
+                b.put("a", numberName(r));
+                mValues[i] = b;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        ContentValues b = new ContentValues(1);
-        b.put("a", r);
-        mValues[i] = b;
-      }
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.insert("t1", null, mValues[i]);
-      }
-    }
-  }
-
-  /**
-   *  10000 inserts for an integer -indexed table
-   */
-
-  public static class InsertIntegerIndex10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    ContentValues[] mValues = new ContentValues[SIZE];
-
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
-
-      mDatabase
-      .execSQL("CREATE TABLE t1(a INTEGER)");
-      mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        ContentValues b = new ContentValues(1);
-        b.put("a", r);
-        mValues[i] = b;
-      }
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.insert("t1", null, mValues[i]);
-      }
-    }
-  }
-
-  /**
-   *  10000 inserts for a String 
-   */
-
-  public static class InsertString10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    ContentValues[] mValues = new ContentValues[SIZE];
-
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
-
-      mDatabase
-      .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        ContentValues b = new ContentValues(1);
-        b.put("a", numberName(r));
-        mValues[i] = b;
-      }
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.insert("t1", null, mValues[i]);
-      }
-    }
-  }
-
-  /**
-   *  10000 inserts for a String - indexed table 
-   */
-
-  public static class InsertStringIndexed10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;       
-    ContentValues[] mValues = new ContentValues[SIZE];
-
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
-
-      mDatabase
-      .execSQL("CREATE TABLE t1(a VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i1a ON t1(a)");
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        ContentValues b = new ContentValues(1);
-        b.put("a", numberName(r));
-        mValues[i] = b; 
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.insert("t1", null, mValues[i]);
+            }
+        }
     }
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.insert("t1", null, mValues[i]);
-      }
+
+    /**
+     *  10000 selects for a String -starts with
+     */
+
+    public static class SelectStringStartsWith10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t3.a"};
+        private String[] where = new String[SIZE];
+
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
+
+            mDatabase
+            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t3 VALUES('"
+                        + numberName(r) + "')");
+            }
+
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
+
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
+    /**
+     *  10000 selects for a String - indexed table -starts with
+     */
 
-  /**
-   *  10000 selects for a String -starts with
-   */
+    public static class SelectStringIndexedStartsWith10000 extends
+    PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t3.a"};
+        private String[] where = new String[SIZE];
 
-  public static class SelectStringStartsWith10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t3.a"};
-    private String[] where = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t3 VALUES('"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t3 VALUES('"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
+            }
+        }
 
-      }
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
-  /**
-   *  10000 selects for a String - indexed table -starts with
-   */
+    /**
+     *  10000 selects for an integer -
+     */
 
-  public static class SelectStringIndexedStartsWith10000 extends
-  PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t3.a"};
-    private String[] where = new String[SIZE];
+    public static class SelectInteger10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t4.a"};
+        private String[] where = new String[SIZE];
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-      mDatabase
-      .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
+            mDatabase
+            .execSQL("CREATE TABLE t4(a INTEGER)");
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t3 VALUES('"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "a >= " + lower + " AND a < " + upper;
+            }
+        }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        where[i] = "a LIKE '" + numberName(r).substring(0, 1) + "*'";
-
-      }                              
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
-  /**
-   *  10000 selects for an integer -
-   */
+    /**
+     *  10000 selects for an integer -indexed table
+     */
 
-  public static class SelectInteger10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t4.a"};
-    private String[] where = new String[SIZE];
+    public static class SelectIntegerIndexed10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t4.a"};
+        private String[] where = new String[SIZE];
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-      mDatabase
-      .execSQL("CREATE TABLE t4(a INTEGER)");
+            mDatabase
+            .execSQL("CREATE TABLE t4(a INTEGER)");
+            mDatabase.execSQL("CREATE INDEX i4a ON t4(a)");
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "a >= " + lower + " AND a < " + upper;
-      }
-    }        
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-      }
+                int lower = i * 100;
+                int upper = (i + 10) * 100;
+                where[i] = "a >= " + lower + " AND a < " + upper;
+            }
+
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
-  /**
-   *  10000 selects for an integer -indexed table
-   */
 
-  public static class SelectIntegerIndexed10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t4.a"};
-    private String[] where = new String[SIZE];
+    /**
+     *  10000 selects for a String - contains 'e'
+     */
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+    public static class SelectStringContains10000 extends PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t3.a"};
+        private String[] where = new String[SIZE];
 
-      mDatabase
-      .execSQL("CREATE TABLE t4(a INTEGER)");
-      mDatabase.execSQL("CREATE INDEX i4a ON t4(a)");
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t4 VALUES(" + r + ")");
+            mDatabase
+            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
 
-        int lower = i * 100;
-        int upper = (i + 10) * 100;
-        where[i] = "a >= " + lower + " AND a < " + upper;
-      }
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t3 VALUES('"
+                        + numberName(r) + "')");
+            }
 
-    }        
+            for (int i = 0; i < SIZE; i++) {
+                where[i] = "a LIKE '*e*'";
 
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t4", COLUMNS, where[i], null, null, null, null);
-      }
+            }
+        }
+
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
+    /**
+     *  10000 selects for a String - contains 'e'-indexed table
+     */
 
-  /**
-   *  10000 selects for a String - contains 'e'
-   */
+    public static class SelectStringIndexedContains10000 extends
+    PerformanceBase {
+        private static final int SIZE = 100 * kMultiplier;
+        private static final String[] COLUMNS = {"t3.a"};
+        private String[] where = new String[SIZE];
 
-  public static class SelectStringContains10000 extends PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t3.a"};
-    private String[] where = new String[SIZE];
+        @Override
+        public void setUp() {
+            super.setUp();
+            Random random = new Random(42);
 
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
+            mDatabase
+            .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
 
-      mDatabase
-      .execSQL("CREATE TABLE t3(a VARCHAR(100))");
+            for (int i = 0; i < SIZE; i++) {
+                int r = random.nextInt(100000);
+                mDatabase.execSQL("INSERT INTO t3 VALUES('"
+                        + numberName(r) + "')");
+            }
 
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t3 VALUES('"
-            + numberName(r) + "')");
-      }
+            for (int i = 0; i < SIZE; i++) {
+                where[i] = "a LIKE '*e*'";
 
-      for (int i = 0; i < SIZE; i++) {
-        where[i] = "a LIKE '*e*'";
+            }
+        }
 
-      }                              
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-      }
+        public void testRun() {
+            for (int i = 0; i < SIZE; i++) {
+                mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
+            }
+        }
     }
-  }
 
-  /**
-   *  10000 selects for a String - contains 'e'-indexed table
-   */
+    public static final String[] ONES =
+        {"zero", "one", "two", "three", "four", "five", "six", "seven",
+        "eight", "nine", "ten", "eleven", "twelve", "thirteen",
+        "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
+        "nineteen"};
 
-  public static class SelectStringIndexedContains10000 extends
-  PerformanceBase {
-    private static final int SIZE = 100 * kMultiplier;
-    private static final String[] COLUMNS = {"t3.a"};
-    private String[] where = new String[SIZE];
-
-    @Override
-    public void setUp() {
-      super.setUp();
-      Random random = new Random(42);
-
-      mDatabase
-      .execSQL("CREATE TABLE t3(a VARCHAR(100))");
-      mDatabase.execSQL("CREATE INDEX i3a ON t3(a)");
-
-      for (int i = 0; i < SIZE; i++) {
-        int r = random.nextInt(100000);
-        mDatabase.execSQL("INSERT INTO t3 VALUES('"
-            + numberName(r) + "')");
-      }
-
-      for (int i = 0; i < SIZE; i++) {
-        where[i] = "a LIKE '*e*'";
-
-      }                              
-    }        
-
-    public void testRun() {
-      for (int i = 0; i < SIZE; i++) {
-        mDatabase.query("t3", COLUMNS, where[i], null, null, null, null);
-      }
-    }
-  }
-
-  public static final String[] ONES =
-  {"zero", "one", "two", "three", "four", "five", "six", "seven",
-    "eight", "nine", "ten", "eleven", "twelve", "thirteen",
-    "fourteen", "fifteen", "sixteen", "seventeen", "eighteen",
-  "nineteen"};
-
-  public static final String[] TENS =
-  {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
-    "seventy", "eighty", "ninety"};
+    public static final String[] TENS =
+        {"", "ten", "twenty", "thirty", "forty", "fifty", "sixty",
+        "seventy", "eighty", "ninety"};
 }
diff --git a/core/tests/coretests/src/android/database/sqlite/DatabaseConnectionPoolTest.java b/core/tests/coretests/src/android/database/sqlite/DatabaseConnectionPoolTest.java
deleted file mode 100644
index 525dd2d..0000000
--- a/core/tests/coretests/src/android/database/sqlite/DatabaseConnectionPoolTest.java
+++ /dev/null
@@ -1,368 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabaseTest.ClassToTestSqlCompilationAndCaching;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.HashMap;
-
-public class DatabaseConnectionPoolTest extends AndroidTestCase {
-    private static final String TAG = "DatabaseConnectionPoolTest";
-
-    private static final int MAX_CONN = 5;
-    private static final String TEST_SQL = "select * from test where i = ? AND j = 1";
-    private static final String[] TEST_SQLS = new String[] {
-        TEST_SQL, TEST_SQL + 1, TEST_SQL + 2, TEST_SQL + 3, TEST_SQL + 4
-    };
-
-    private SQLiteDatabase mDatabase;
-    private File mDatabaseFile;
-    private DatabaseConnectionPool mTestPool;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
-        mDatabaseFile = new File(dbDir, "database_test.db");
-        if (mDatabaseFile.exists()) {
-            mDatabaseFile.delete();
-        }
-        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
-        assertNotNull(mDatabase);
-        mDatabase.execSQL("create table test (i int, j int);");
-        mTestPool = new DatabaseConnectionPool(mDatabase);
-        assertNotNull(mTestPool);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mTestPool.close();
-        mDatabase.close();
-        mDatabaseFile.delete();
-        super.tearDown();
-    }
-
-    @SmallTest
-    public void testGetAndRelease() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-        // connections should be lazily created.
-        assertEquals(0, mTestPool.getSize());
-        // MAX pool size should be set to MAX_CONN
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // get a connection
-        SQLiteDatabase db = mTestPool.get(TEST_SQL);
-        // pool size should be one - since only one should be allocated for the above get()
-        assertEquals(1, mTestPool.getSize());
-        assertEquals(mDatabase, db.mParentConnObj);
-        // no free connections should be available
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertFalse(mTestPool.isDatabaseObjFree(db));
-        // release the connection
-        mTestPool.release(db);
-        assertEquals(1, mTestPool.getFreePoolSize());
-        assertEquals(1, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        assertTrue(mTestPool.isDatabaseObjFree(db));
-        // release the same object again and expect IllegalStateException
-        try {
-            mTestPool.release(db);
-            fail("illegalStateException expected");
-        } catch (IllegalStateException e ) {
-            // expected.
-        }
-    }
-
-    /**
-     * get all connections from the pool and ask for one more.
-     * should get one of the connections already got so far. 
-     */
-    @SmallTest
-    public void testGetAllConnAndOneMore() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        ArrayList<SQLiteDatabase> dbObjs = new ArrayList<SQLiteDatabase>();
-        for (int i = 0; i < MAX_CONN; i++) {
-            SQLiteDatabase db = mTestPool.get(TEST_SQL);
-            assertFalse(dbObjs.contains(db));
-            dbObjs.add(db);
-            assertEquals(mDatabase, db.mParentConnObj);
-        }
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // pool is maxed out and no free connections. ask for one more connection
-        SQLiteDatabase db1 = mTestPool.get(TEST_SQL);
-        // make sure db1 is one of the existing ones
-        assertTrue(dbObjs.contains(db1));
-        // pool size should remain at MAX_CONN
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // release db1 but since it is allocated 2 times, it should still remain 'busy'
-        mTestPool.release(db1);
-        assertFalse(mTestPool.isDatabaseObjFree(db1));
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // release all connections
-        for (int i = 0; i < MAX_CONN; i++) {
-            mTestPool.release(dbObjs.get(i));
-        }
-        // all objects in the pool should be freed now
-        assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-    }
-    
-    /**
-     * same as above except that each connection has different SQL statement associated with it. 
-     */
-    @SmallTest
-    public void testConnRetrievalForPreviouslySeenSql() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        HashMap<String, SQLiteDatabase> dbObjs = new HashMap<String, SQLiteDatabase>();
-        for (int i = 0; i < MAX_CONN; i++) {
-            SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
-            executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
-            assertFalse(dbObjs.values().contains(db));
-            dbObjs.put(TEST_SQLS[i], db);
-        }
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // pool is maxed out and no free connections. ask for one more connection
-        // use a previously seen SQL statement
-        String testSql = TEST_SQLS[MAX_CONN - 1];
-        SQLiteDatabase db1 = mTestPool.get(testSql);
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // make sure db1 is one of the existing ones
-        assertTrue(dbObjs.values().contains(db1));
-        assertEquals(db1, dbObjs.get(testSql));
-        // do the same again
-        SQLiteDatabase db2 = mTestPool.get(testSql);
-        // make sure db1 is one of the existing ones
-        assertEquals(db2, dbObjs.get(testSql));
-
-        // pool size should remain at MAX_CONN
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        // release db1 but since the same connection is allocated 3 times,
-        // it should still remain 'busy'
-        mTestPool.release(db1);
-        assertFalse(mTestPool.isDatabaseObjFree(dbObjs.get(testSql)));
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        // release db2 but since the same connection is allocated 2 times,
-        // it should still remain 'busy'
-        mTestPool.release(db2);
-        assertFalse(mTestPool.isDatabaseObjFree(dbObjs.get(testSql)));
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        // release all connections
-        for (int i = 0; i < MAX_CONN; i++) {
-            mTestPool.release(dbObjs.get(TEST_SQLS[i]));
-        }
-        // all objects in the pool should be freed now
-        assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-    }
-
-    private void executeSqlOnDatabaseConn(SQLiteDatabase db, String sql) {
-        // get the given sql be compiled on the given database connection.
-        // this will help DatabaseConenctionPool figure out if a given SQL statement
-        // is already cached by a database connection.
-        ClassToTestSqlCompilationAndCaching c =
-                ClassToTestSqlCompilationAndCaching.create(db, sql);
-        c.close();
-    }
-
-    /**
-     * get a connection for a SQL statement 'blah'. (connection_s)
-     * make sure the pool has at least one free connection even after this get().
-     * and get a connection for the same SQL again.
-     *    this connection should be different from connection_s.
-     *    even though there is a connection with the given SQL pre-compiled, since is it not free
-     *    AND since the pool has free connections available, should get a new connection.
-     */
-    @SmallTest
-    public void testGetConnForTheSameSql() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-
-        SQLiteDatabase db = mTestPool.get(TEST_SQL);
-        executeSqlOnDatabaseConn(db, TEST_SQL);
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(1, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        assertFalse(mTestPool.isDatabaseObjFree(db));
-
-        SQLiteDatabase db1 = mTestPool.get(TEST_SQL);
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(2, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        assertFalse(mTestPool.isDatabaseObjFree(db1));
-        assertFalse(db1.equals(db));
-
-        mTestPool.release(db);
-        assertEquals(1, mTestPool.getFreePoolSize());
-        assertEquals(2, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        mTestPool.release(db1);
-        assertEquals(2, mTestPool.getFreePoolSize());
-        assertEquals(2, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-    }
-
-    /**
-     * get the same connection N times and release it N times.
-     * this tests DatabaseConnectionPool.PoolObj.mNumHolders
-     */
-    @SmallTest
-    public void testGetSameConnNtimesAndReleaseItNtimes() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        HashMap<String, SQLiteDatabase> dbObjs = new HashMap<String, SQLiteDatabase>();
-        for (int i = 0; i < MAX_CONN; i++) {
-            SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
-            executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
-            assertFalse(dbObjs.values().contains(db));
-            dbObjs.put(TEST_SQLS[i], db);
-        }
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // every connection in the pool should have numHolders = 1
-        for (int i = 0; i < MAX_CONN; i ++) {
-            assertEquals(1, mTestPool.getPool().get(i).getNumHolders());
-        }
-        // pool is maxed out and no free connections. ask for one more connection
-        // use a previously seen SQL statement
-        String testSql = TEST_SQLS[MAX_CONN - 1];
-        SQLiteDatabase db1 = mTestPool.get(testSql);
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // make sure db1 is one of the existing ones
-        assertTrue(dbObjs.values().contains(db1));
-        assertEquals(db1, dbObjs.get(testSql));
-        assertFalse(mTestPool.isDatabaseObjFree(db1));
-        DatabaseConnectionPool.PoolObj poolObj = mTestPool.getPool().get(db1.mConnectionNum - 1);
-        int numHolders = poolObj.getNumHolders();
-        assertEquals(2, numHolders);
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // get the same connection N times more
-        int N = 100;
-        for (int i = 0; i < N; i++) {
-            SQLiteDatabase db2 = mTestPool.get(testSql);
-            assertEquals(db1, db2);
-            assertFalse(mTestPool.isDatabaseObjFree(db2));
-            // numHolders for this object should be now up by 1
-            int prev = numHolders;
-            numHolders = poolObj.getNumHolders();
-            assertEquals(prev + 1, numHolders);
-        }
-        // release it N times
-        for (int i = 0; i < N; i++) {
-            mTestPool.release(db1);
-            int prev = numHolders;
-            numHolders = poolObj.getNumHolders();
-            assertEquals(prev - 1, numHolders);
-            assertFalse(mTestPool.isDatabaseObjFree(db1));
-        }
-        // the connection should still have 2 more holders
-        assertFalse(mTestPool.isDatabaseObjFree(db1));
-        assertEquals(2, poolObj.getNumHolders());
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // release 2 more times
-        mTestPool.release(db1);
-        mTestPool.release(db1);
-        assertEquals(0, poolObj.getNumHolders());
-        assertEquals(1, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        assertTrue(mTestPool.isDatabaseObjFree(db1));
-    }
-
-    @SmallTest
-    public void testStressTest() {
-        mTestPool.setMaxPoolSize(MAX_CONN);
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-
-        HashMap<SQLiteDatabase, Integer> dbMap = new HashMap<SQLiteDatabase, Integer>();
-        for (int i = 0; i < MAX_CONN; i++) {
-            SQLiteDatabase db = mTestPool.get(TEST_SQLS[i]);
-            assertFalse(dbMap.containsKey(db));
-            dbMap.put(db, 1);
-            executeSqlOnDatabaseConn(db, TEST_SQLS[i]);
-        }
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // ask for lot more connections but since the pool is maxed out, we should start receiving
-        // connections that we already got so far
-        for (int i = MAX_CONN; i < 1000; i++) {
-            SQLiteDatabase db = mTestPool.get(TEST_SQL + i);
-            assertTrue(dbMap.containsKey(db));
-            int k = dbMap.get(db);
-            dbMap.put(db, ++k);
-        }
-        assertEquals(0, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-        // print the distribution of the database connection handles received, should be uniform.
-        for (SQLiteDatabase d : dbMap.keySet()) {
-            Log.i(TAG, "connection # " + d.mConnectionNum + ", numHolders: " + dbMap.get(d));
-        }
-        // print the pool info
-        Log.i(TAG, mTestPool.toString());
-        // release all
-        for (SQLiteDatabase d : dbMap.keySet()) {
-            int num = dbMap.get(d);
-            for (int i = 0; i < num; i++) {
-                mTestPool.release(d);
-            }
-        }
-        assertEquals(MAX_CONN, mTestPool.getFreePoolSize());
-        assertEquals(MAX_CONN, mTestPool.getSize());
-        assertEquals(MAX_CONN, mTestPool.getMaxPoolSize());
-    }
-}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
index f6b1d04..9ccc6e8 100644
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
+++ b/core/tests/coretests/src/android/database/sqlite/SQLiteCursorTest.java
@@ -21,8 +21,6 @@
 import android.database.Cursor;
 import android.test.AndroidTestCase;
 import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.util.Log;
 
 import java.io.File;
 import java.util.HashSet;
@@ -54,52 +52,8 @@
         super.tearDown();
     }
 
-    @SmallTest
-    public void testQueryObjReassignment() {
-        mDatabase.enableWriteAheadLogging();
-        // have a few connections in the database connection pool
-        DatabaseConnectionPool pool = mDatabase.mConnectionPool;
-        pool.setMaxPoolSize(5);
-        SQLiteCursor cursor =
-                (SQLiteCursor) mDatabase.rawQuery("select * from " + TABLE_NAME, null);
-        assertNotNull(cursor);
-        // it should use a pooled database connection
-        SQLiteDatabase db = cursor.getDatabase();
-        assertTrue(db.mConnectionNum > 0);
-        assertFalse(mDatabase.equals(db));
-        assertEquals(mDatabase, db.mParentConnObj);
-        assertTrue(pool.getConnectionList().contains(db));
-        assertTrue(db.isOpen());
-        // do a requery. cursor should continue to use the above pooled connection
-        cursor.requery();
-        SQLiteDatabase dbAgain = cursor.getDatabase();
-        assertEquals(db, dbAgain);
-        // disable WAL so that the pooled connection held by the above cursor is closed
-        mDatabase.disableWriteAheadLogging();
-        assertFalse(db.isOpen());
-        assertNull(mDatabase.mConnectionPool);
-        // requery - which should make the cursor use mDatabase connection since the pooled
-        // connection is no longer available
-        cursor.requery();
-        SQLiteDatabase db1 = cursor.getDatabase();
-        assertTrue(db1.mConnectionNum == 0);
-        assertEquals(mDatabase, db1);
-        assertNull(mDatabase.mConnectionPool);
-        assertTrue(db1.isOpen());
-        assertFalse(mDatabase.equals(db));
-        // enable WAL and requery - this time a pooled connection should be used
-        mDatabase.enableWriteAheadLogging();
-        cursor.requery();
-        db = cursor.getDatabase();
-        assertTrue(db.mConnectionNum > 0);
-        assertFalse(mDatabase.equals(db));
-        assertEquals(mDatabase, db.mParentConnObj);
-        assertTrue(mDatabase.mConnectionPool.getConnectionList().contains(db));
-        assertTrue(db.isOpen());
-    }
-
     /**
-     * this test could take a while to execute. so, designate it as LargetTest
+     * this test could take a while to execute. so, designate it as LargeTest
      */
     @LargeTest
     public void testFillWindow() {
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
deleted file mode 100644
index 5ef8d11..0000000
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteDatabaseTest.java
+++ /dev/null
@@ -1,971 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.content.ContentValues;
-import android.content.Context;
-import android.database.Cursor;
-import android.database.DatabaseErrorHandler;
-import android.database.DatabaseUtils;
-import android.database.DefaultDatabaseErrorHandler;
-import android.database.sqlite.SQLiteDatabase;
-import android.database.sqlite.SQLiteDatabase.CursorFactory;
-import android.database.sqlite.SQLiteStatement;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.MediumTest;
-import android.test.suitebuilder.annotation.SmallTest;
-import android.test.suitebuilder.annotation.Suppress;
-import android.util.Log;
-import android.util.Pair;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-public class SQLiteDatabaseTest extends AndroidTestCase {
-    private static final String TAG = "DatabaseGeneralTest";
-    private static final String TEST_TABLE = "test";
-    private static final int CURRENT_DATABASE_VERSION = 42;
-    private SQLiteDatabase mDatabase;
-    private File mDatabaseFile;
-    private static final int INSERT = 1;
-    private static final int UPDATE = 2;
-    private static final int DELETE = 3;
-    private static final String DB_NAME = "database_test.db";
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-        dbSetUp();
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        dbTeardown();
-        super.tearDown();
-    }
-
-    private void dbTeardown() throws Exception {
-        mDatabase.close();
-        mDatabaseFile.delete();
-    }
-
-    private void dbSetUp() throws Exception {
-        File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
-        mDatabaseFile = new File(dbDir, DB_NAME);
-        if (mDatabaseFile.exists()) {
-            mDatabaseFile.delete();
-        }
-        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null, null);
-        assertNotNull(mDatabase);
-        mDatabase.setVersion(CURRENT_DATABASE_VERSION);
-    }
-
-    @SmallTest
-    public void testEnableWriteAheadLogging() {
-        mDatabase.disableWriteAheadLogging();
-        assertNull(mDatabase.mConnectionPool);
-        mDatabase.enableWriteAheadLogging();
-        DatabaseConnectionPool pool = mDatabase.mConnectionPool;
-        assertNotNull(pool);
-        // make the same call again and make sure the pool already setup is not re-created
-        mDatabase.enableWriteAheadLogging();
-        assertEquals(pool, mDatabase.mConnectionPool);
-    }
-
-    @SmallTest
-    public void testDisableWriteAheadLogging() {
-        mDatabase.execSQL("create table test (i int);");
-        mDatabase.enableWriteAheadLogging();
-        assertNotNull(mDatabase.mConnectionPool);
-        // get a pooled database connection
-        SQLiteDatabase db = mDatabase.getDbConnection("select * from test");
-        assertNotNull(db);
-        assertFalse(mDatabase.equals(db));
-        assertTrue(db.isOpen());
-        // disable WAL - which should close connection pool and all pooled connections
-        mDatabase.disableWriteAheadLogging();
-        assertNull(mDatabase.mConnectionPool);
-        assertFalse(db.isOpen());
-    }
-
-    @SmallTest
-    public void testCursorsWithClosedDbConnAfterDisableWriteAheadLogging() {
-        mDatabase.disableWriteAheadLogging();
-        mDatabase.beginTransactionNonExclusive();
-        mDatabase.execSQL("create table test (i int);");
-        mDatabase.execSQL("insert into test values(1);");
-        mDatabase.setTransactionSuccessful();
-        mDatabase.endTransaction();
-        mDatabase.enableWriteAheadLogging();
-        assertNotNull(mDatabase.mConnectionPool);
-        assertEquals(0, mDatabase.mConnectionPool.getSize());
-        assertEquals(0, mDatabase.mConnectionPool.getFreePoolSize());
-        // get a cursor which should use pooled database connection
-        Cursor c = mDatabase.rawQuery("select * from test", null);
-        assertEquals(1, c.getCount());
-        assertEquals(1, mDatabase.mConnectionPool.getSize());
-        assertEquals(1, mDatabase.mConnectionPool.getFreePoolSize());
-        SQLiteDatabase db = mDatabase.mConnectionPool.getConnectionList().get(0);
-        assertTrue(mDatabase.mConnectionPool.isDatabaseObjFree(db));
-        // disable WAL - which should close connection pool and all pooled connections
-        mDatabase.disableWriteAheadLogging();
-        assertNull(mDatabase.mConnectionPool);
-        assertFalse(db.isOpen());
-        // cursor data should still be accessible because it is fetching data from CursorWindow
-        c.moveToNext();
-        assertEquals(1, c.getInt(0));
-        c.requery();
-        assertEquals(1, c.getCount());
-        c.moveToNext();
-        assertEquals(1, c.getInt(0));
-        c.close();
-    }
-
-    /**
-     * a transaction should be started before a standalone-update/insert/delete statement
-     */
-    @SmallTest
-    public void testStartXactBeforeUpdateSql() throws InterruptedException {
-        runTestForStartXactBeforeUpdateSql(INSERT);
-        runTestForStartXactBeforeUpdateSql(UPDATE);
-        runTestForStartXactBeforeUpdateSql(DELETE);
-    }
-    private void runTestForStartXactBeforeUpdateSql(int stmtType) throws InterruptedException {
-        createTableAndClearCache();
-
-        ContentValues values = new ContentValues();
-        // make some changes to data in TEST_TABLE
-        for (int i = 0; i < 5; i++) {
-            values.put("i", i);
-            values.put("j", "i" + System.currentTimeMillis());
-            mDatabase.insert(TEST_TABLE, null, values);
-            switch (stmtType) {
-                case UPDATE:
-                    values.put("j", "u" + System.currentTimeMillis());
-                    mDatabase.update(TEST_TABLE, values, "i = " + i, null);
-                    break;
-                case DELETE:
-                    mDatabase.delete(TEST_TABLE, "i = 1", null);
-                    break;
-            }
-        }
-        // do a query. even though query uses a different database connection,
-        // it should still see the above changes to data because the above standalone
-        // insert/update/deletes are done in transactions automatically.
-        String sql = "select count(*) from " + TEST_TABLE;
-        SQLiteStatement stmt = mDatabase.compileStatement(sql);
-        final int expectedValue = (stmtType == DELETE) ? 4 : 5;
-        assertEquals(expectedValue, stmt.simpleQueryForLong());
-        stmt.close();
-        Cursor c = mDatabase.rawQuery(sql, null);
-        assertEquals(1, c.getCount());
-        c.moveToFirst();
-        assertEquals(expectedValue, c.getLong(0));
-        c.close();
-
-        // do 5 more changes in a transaction but do a query before and after the commit
-        mDatabase.beginTransaction();
-        for (int i = 10; i < 15; i++) {
-            values.put("i", i);
-            values.put("j", "i" + System.currentTimeMillis());
-            mDatabase.insert(TEST_TABLE, null, values);
-            switch (stmtType) {
-                case UPDATE:
-                    values.put("j", "u" + System.currentTimeMillis());
-                    mDatabase.update(TEST_TABLE, values, "i = " + i, null);
-                    break;
-                case DELETE:
-                    mDatabase.delete(TEST_TABLE, "i = 1", null);
-                    break;
-            }
-        }
-        mDatabase.setTransactionSuccessful();
-        // do a query before commit - should still have 5 rows
-        // this query should run in a different thread to force it to use a different database
-        // connection
-        Thread t = new Thread() {
-            @Override public void run() {
-                String sql = "select count(*) from " + TEST_TABLE;
-                SQLiteStatement stmt = getDb().compileStatement(sql);
-                assertEquals(expectedValue, stmt.simpleQueryForLong());
-                stmt.close();
-                Cursor c = getDb().rawQuery(sql, null);
-                assertEquals(1, c.getCount());
-                c.moveToFirst();
-                assertEquals(expectedValue, c.getLong(0));
-                c.close();
-            }
-        };
-        t.start();
-        // wait until the above thread is done
-        t.join();
-        // commit and then query. should see changes from the transaction
-        mDatabase.endTransaction();
-        stmt = mDatabase.compileStatement(sql);
-        final int expectedValue2 = (stmtType == DELETE) ? 9 : 10;
-        assertEquals(expectedValue2, stmt.simpleQueryForLong());
-        stmt.close();
-        c = mDatabase.rawQuery(sql, null);
-        assertEquals(1, c.getCount());
-        c.moveToFirst();
-        assertEquals(expectedValue2, c.getLong(0));
-        c.close();
-    }
-    private synchronized SQLiteDatabase getDb() {
-        return mDatabase;
-    }
-
-    /**
-     * Test to ensure that readers are able to read the database data (old versions)
-     * EVEN WHEN the writer is in a transaction on the same database.
-     *<p>
-     * This test starts 1 Writer and 2 Readers and sets up connection pool for readers
-     * by calling the method {@link SQLiteDatabase#enableWriteAheadLogging()}.
-     * <p>
-     * Writer does the following in a tight loop
-     * <pre>
-     *     begin transaction
-     *     insert into table_1
-     *     insert into table_2
-     *     commit
-     * </pre>
-     * <p>
-     * As long a the writer is alive, Readers do the following in a tight loop at the same time
-     * <pre>
-     *     Reader_K does "select count(*) from table_K"  where K = 1 or 2
-     * </pre>
-     * <p>
-     * The test is run for TIME_TO_RUN_WAL_TEST_FOR sec.
-     * <p>
-     * The test is repeated for different connection-pool-sizes (1..3)
-     * <p>
-     * And at the end of of each test, the following statistics are printed
-     * <ul>
-     *    <li>connection-pool-size</li>
-     *    <li>number-of-transactions by writer</li>
-     *    <li>number of reads by reader_K while the writer is IN or NOT-IN xaction</li>
-     * </ul>
-     */
-    @LargeTest
-    @Suppress // run this test only if you need to collect the numbers from this test
-    public void testConcurrencyEffectsOfConnPool() throws Exception {
-        // run the test with sqlite WAL enable
-        runConnectionPoolTest(true);
-
-        // run the same test WITHOUT sqlite WAL enabled
-        runConnectionPoolTest(false);
-    }
-
-    private void runConnectionPoolTest(boolean useWal) throws Exception {
-        int M = 3;
-        StringBuilder[] buff = new StringBuilder[M];
-        for (int i = 0; i < M; i++) {
-            if (useWal) {
-                // set up connection pool
-                mDatabase.enableWriteAheadLogging();
-                mDatabase.mConnectionPool.setMaxPoolSize(i + 1);
-            } else {
-                mDatabase.disableWriteAheadLogging();
-            }
-            mDatabase.execSQL("CREATE TABLE t1 (i int, j int);");
-            mDatabase.execSQL("CREATE TABLE t2 (i int, j int);");
-            mDatabase.beginTransaction();
-            for (int k = 0; k < 5; k++) {
-                mDatabase.execSQL("insert into t1 values(?,?);", new String[] {k+"", k+""});
-                mDatabase.execSQL("insert into t2 values(?,?);", new String[] {k+"", k+""});
-            }
-            mDatabase.setTransactionSuccessful();
-            mDatabase.endTransaction();
-
-            // start a writer
-            Writer w = new Writer(mDatabase);
-
-            // initialize an array of counters to be passed to the readers
-            Reader r1 = new Reader(mDatabase, "t1", w, 0);
-            Reader r2 = new Reader(mDatabase, "t2", w, 1);
-            w.start();
-            r1.start();
-            r2.start();
-
-            // wait for all threads to die
-            w.join();
-            r1.join();
-            r2.join();
-
-            // print the stats
-            int[][] counts = getCounts();
-            buff[i] = new StringBuilder();
-            buff[i].append("connpool-size = ");
-            buff[i].append(i + 1);
-            buff[i].append(", num xacts by writer = ");
-            buff[i].append(getNumXacts());
-            buff[i].append(", num-reads-in-xact/NOT-in-xact by reader1 = ");
-            buff[i].append(counts[0][1] + "/" + counts[0][0]);
-            buff[i].append(", by reader2 = ");
-            buff[i].append(counts[1][1] + "/" + counts[1][0]);
-
-            Log.i(TAG, "done testing for conn-pool-size of " + (i+1));
-
-            dbTeardown();
-            dbSetUp();
-        }
-        Log.i(TAG, "duration of test " + TIME_TO_RUN_WAL_TEST_FOR + " sec");
-        for (int i = 0; i < M; i++) {
-            Log.i(TAG, buff[i].toString());
-        }
-    }
-
-    private boolean inXact = false;
-    private int numXacts;
-    private static final int TIME_TO_RUN_WAL_TEST_FOR = 15; // num sec this test should run
-    private int[][] counts = new int[2][2];
-
-    private synchronized boolean inXact() {
-        return inXact;
-    }
-
-    private synchronized void setInXactFlag(boolean flag) {
-        inXact = flag;
-    }
-
-    private synchronized void setCounts(int readerNum, int[] numReads) {
-        counts[readerNum][0] = numReads[0];
-        counts[readerNum][1] = numReads[1];
-    }
-
-    private synchronized int[][] getCounts() {
-        return counts;
-    }
-
-    private synchronized void setNumXacts(int num) {
-        numXacts = num;
-    }
-
-    private synchronized int getNumXacts() {
-        return numXacts;
-    }
-
-    private class Writer extends Thread {
-        private SQLiteDatabase db = null;
-        public Writer(SQLiteDatabase db) {
-            this.db = db;
-        }
-        @Override public void run() {
-            // in a loop, for N sec, do the following
-            //    BEGIN transaction
-            //    insert into table t1, t2
-            //    Commit
-            long now = System.currentTimeMillis();
-            int k;
-            for (k = 0;(System.currentTimeMillis() - now) / 1000 < TIME_TO_RUN_WAL_TEST_FOR; k++) {
-                db.beginTransactionNonExclusive();
-                setInXactFlag(true);
-                for (int i = 0; i < 10; i++) {
-                    db.execSQL("insert into t1 values(?,?);", new String[] {i+"", i+""});
-                    db.execSQL("insert into t2 values(?,?);", new String[] {i+"", i+""});
-                }
-                db.setTransactionSuccessful();
-                setInXactFlag(false);
-                db.endTransaction();
-            }
-            setNumXacts(k);
-        }
-    }
-
-    private class Reader extends Thread {
-        private SQLiteDatabase db = null;
-        private String table = null;
-        private Writer w = null;
-        private int readerNum;
-        private int[] numReads = new int[2];
-        public Reader(SQLiteDatabase db, String table, Writer w, int readerNum) {
-            this.db = db;
-            this.table = table;
-            this.w = w;
-            this.readerNum = readerNum;
-        }
-        @Override public void run() {
-            // while the write is alive, in a loop do the query on a table
-            while (w.isAlive()) {
-                for (int i = 0; i < 10; i++) {
-                    DatabaseUtils.longForQuery(db, "select count(*) from " + this.table, null);
-                    // update count of reads
-                    numReads[inXact() ? 1 : 0] += 1;
-                }
-            }
-            setCounts(readerNum, numReads);
-        }
-    }
-
-    public static class ClassToTestSqlCompilationAndCaching extends SQLiteProgram {
-        private ClassToTestSqlCompilationAndCaching(SQLiteDatabase db, String sql) {
-            super(db, sql);
-        }
-        public static ClassToTestSqlCompilationAndCaching create(SQLiteDatabase db, String sql) {
-            db.lock();
-            try {
-                return new ClassToTestSqlCompilationAndCaching(db, sql);
-            } finally {
-                db.unlock();
-            }
-        }
-    }
-
-    @SmallTest
-    public void testLruCachingOfSqliteCompiledSqlObjs() {
-        createTableAndClearCache();
-        // set cache size
-        int N = SQLiteDatabase.MAX_SQL_CACHE_SIZE;
-        mDatabase.setMaxSqlCacheSize(N);
-
-        // do N+1 queries - and when the 0th entry is removed from LRU cache due to the
-        // insertion of (N+1)th entry, make sure 0th entry is closed
-        ArrayList<Integer> stmtObjs = new ArrayList<Integer>();
-        ArrayList<String> sqlStrings = new ArrayList<String>();
-        int stmt0 = 0;
-        for (int i = 0; i < N+1; i++) {
-            String s = "insert into test values(" + i + ",?);";
-            sqlStrings.add(s);
-            ClassToTestSqlCompilationAndCaching c =
-                    ClassToTestSqlCompilationAndCaching.create(mDatabase, s);
-            int n = c.getSqlStatementId();
-            stmtObjs.add(i, n);
-            if (i == 0) {
-                // save the statementId of this obj. we want to make sure it is thrown out of
-                // the cache at the end of this test.
-                stmt0 = n;
-            }
-            c.close();
-        }
-        // is 0'th entry out of the cache? it should be in the list of statementIds
-        // corresponding to the pre-compiled sql statements to be finalized.
-        assertTrue(mDatabase.getQueuedUpStmtList().contains(stmt0));
-        for (int i = 1; i < N+1; i++) {
-            SQLiteCompiledSql compSql = mDatabase.getCompiledStatementForSql(sqlStrings.get(i));
-            assertNotNull(compSql);
-            assertTrue(stmtObjs.contains(compSql.nStatement));
-        }
-    }
-
-    @MediumTest
-    public void testDbCloseReleasingAllCachedSql() {
-        mDatabase.execSQL("CREATE TABLE test (_id INTEGER PRIMARY KEY, text1 TEXT, text2 TEXT, " +
-                "num1 INTEGER, num2 INTEGER, image BLOB);");
-        final String statement = "DELETE FROM test WHERE _id=?;";
-        SQLiteStatement statementDoNotClose = mDatabase.compileStatement(statement);
-        statementDoNotClose.bindLong(1, 1);
-        /* do not close statementDoNotClose object.
-         * That should leave it in SQLiteDatabase.mPrograms.
-         * mDatabase.close() in tearDown() should release it.
-         */
-    }
-
-    private void createTableAndClearCache() {
-        mDatabase.disableWriteAheadLogging();
-        mDatabase.execSQL("DROP TABLE IF EXISTS " + TEST_TABLE);
-        mDatabase.execSQL("CREATE TABLE " + TEST_TABLE + " (i int, j int);");
-        mDatabase.enableWriteAheadLogging();
-        mDatabase.lock();
-        // flush the above statement from cache and close all the pending statements to be released
-        mDatabase.deallocCachedSqlStatements();
-        mDatabase.closePendingStatements();
-        mDatabase.unlock();
-        assertEquals(0, mDatabase.getQueuedUpStmtList().size());
-    }
-
-    /**
-     * test to make sure the statement finalizations are not done right away but
-     * piggy-backed onto the next sql statement execution on the same database.
-     */
-    @SmallTest
-    public void testStatementClose() {
-        createTableAndClearCache();
-        // fill up statement cache in mDatabase
-        int N = SQLiteDatabase.MAX_SQL_CACHE_SIZE;
-        mDatabase.setMaxSqlCacheSize(N);
-        SQLiteStatement stmt;
-        int stmt0Id = 0;
-        for (int i = 0; i < N; i ++) {
-            ClassToTestSqlCompilationAndCaching c =
-                    ClassToTestSqlCompilationAndCaching.create(mDatabase,
-                            "insert into test values(" + i + ", ?);");
-            // keep track of 0th entry
-            if (i == 0) {
-                stmt0Id = c.getSqlStatementId();
-            }
-            c.close();
-        }
-
-        // add one more to the cache - and the above 'stmt0Id' should fall out of cache
-        ClassToTestSqlCompilationAndCaching stmt1 =
-                ClassToTestSqlCompilationAndCaching.create(mDatabase,
-                        "insert into test values(100, ?);");
-        stmt1.close();
-
-        // the above close() should have queuedUp the statement for finalization
-        ArrayList<Integer> statementIds = mDatabase.getQueuedUpStmtList();
-        assertTrue(statementIds.contains(stmt0Id));
-
-        // execute something to see if this statement gets finalized
-        mDatabase.execSQL("delete from test where i = 10;");
-        statementIds = mDatabase.getQueuedUpStmtList();
-        assertFalse(statementIds.contains(stmt0Id));
-    }
-
-    /**
-     * same as above - except that the statement to be finalized is from Thread # 1.
-     * and it is eventually finalized in Thread # 2 when it executes a SQL statement.
-     * @throws InterruptedException
-     */
-    @LargeTest
-    public void testStatementCloseDiffThread() throws InterruptedException {
-        createTableAndClearCache();
-        final int N = SQLiteDatabase.MAX_SQL_CACHE_SIZE;
-        mDatabase.setMaxSqlCacheSize(N);
-        // fill up statement cache in mDatabase in a thread
-        Thread t1 = new Thread() {
-            @Override public void run() {
-                SQLiteStatement stmt;
-                for (int i = 0; i < N; i++) {
-                    ClassToTestSqlCompilationAndCaching c =
-                        ClassToTestSqlCompilationAndCaching.create(getDb(),
-                                "insert into test values(" + i + ", ?);");
-                    // keep track of 0th entry
-                    if (i == 0) {
-                        stmt0Id = c.getSqlStatementId();
-                    }
-                    c.close();
-                }
-            }
-        };
-        t1.start();
-        // wait for the thread to finish
-        t1.join();
-        // mDatabase shouldn't have any statements to be released
-        assertEquals(0, mDatabase.getQueuedUpStmtList().size());
-
-        // add one more to the cache - and the above 'stmt0Id' should fall out of cache
-        // just for the heck of it, do it in a separate thread
-        Thread t2 = new Thread() {
-            @Override public void run() {
-                ClassToTestSqlCompilationAndCaching stmt1 =
-                    ClassToTestSqlCompilationAndCaching.create(getDb(),
-                            "insert into test values(100, ?);");
-                stmt1.bindLong(1, 1);
-                stmt1.close();
-            }
-        };
-        t2.start();
-        t2.join();
-
-        // close() in the above thread should have queuedUp the stmt0Id for finalization
-        ArrayList<Integer> statementIds = getDb().getQueuedUpStmtList();
-        assertTrue(statementIds.contains(getStmt0Id()));
-        assertEquals(1, statementIds.size());
-
-        // execute something to see if this statement gets finalized
-        // again do it in a separate thread
-        Thread t3 = new Thread() {
-            @Override public void run() {
-                getDb().execSQL("delete from test where i = 10;");
-            }
-        };
-        t3.start();
-        t3.join();
-
-        // is the statement finalized?
-        statementIds = getDb().getQueuedUpStmtList();
-        assertFalse(statementIds.contains(getStmt0Id()));
-    }
-
-    private volatile int stmt0Id = 0;
-    private synchronized int getStmt0Id() {
-        return this.stmt0Id;
-    }
-
-    /**
-     * same as above - except that the queue of statements to be finalized are finalized
-     * by database close() operation.
-     */
-    @LargeTest
-    public void testStatementCloseByDbClose() throws InterruptedException {
-        createTableAndClearCache();
-        // fill up statement cache in mDatabase in a thread
-        Thread t1 = new Thread() {
-            @Override public void run() {
-                int N = SQLiteDatabase.MAX_SQL_CACHE_SIZE;
-                getDb().setMaxSqlCacheSize(N);
-                SQLiteStatement stmt;
-                for (int i = 0; i < N; i ++) {
-                    ClassToTestSqlCompilationAndCaching c =
-                            ClassToTestSqlCompilationAndCaching.create(getDb(),
-                                    "insert into test values(" + i + ", ?);");
-                    // keep track of 0th entry
-                    if (i == 0) {
-                        stmt0Id = c.getSqlStatementId();
-                    }
-                    c.close();
-                }
-            }
-        };
-        t1.start();
-        // wait for the thread to finish
-        t1.join();
-
-        // add one more to the cache - and the above 'stmt0Id' should fall out of cache
-        // just for the heck of it, do it in a separate thread
-        Thread t2 = new Thread() {
-            @Override public void run() {
-                ClassToTestSqlCompilationAndCaching stmt1 =
-                        ClassToTestSqlCompilationAndCaching.create(getDb(),
-                                "insert into test values(100, ?);");
-                stmt1.bindLong(1, 1);
-                stmt1.close();
-            }
-        };
-        t2.start();
-        t2.join();
-
-        // close() in the above thread should have queuedUp the statement for finalization
-        ArrayList<Integer> statementIds = getDb().getQueuedUpStmtList();
-        assertTrue(getStmt0Id() > 0);
-        assertTrue(statementIds.contains(stmt0Id));
-        assertEquals(1, statementIds.size());
-
-        // close the database. everything from mClosedStatementIds in mDatabase
-        // should be finalized and cleared from the list
-        // again do it in a separate thread
-        Thread t3 = new Thread() {
-            @Override public void run() {
-                getDb().close();
-            }
-        };
-        t3.start();
-        t3.join();
-
-        // check mClosedStatementIds in mDatabase. it should be empty
-        statementIds = getDb().getQueuedUpStmtList();
-        assertEquals(0, statementIds.size());
-    }
-
-    /**
-     * This test tests usage execSQL() to begin transaction works in the following way
-     *   Thread #1 does
-     *       execSQL("begin transaction");
-     *       insert()
-     *   Thread # 2
-     *       query()
-     *   Thread#1 ("end transaction")
-     * Thread # 2 query will execute - because java layer will not have locked the SQLiteDatabase
-     * object and sqlite will consider this query to be part of the transaction.
-     *
-     * but if thread # 1 uses beginTransaction() instead of execSQL() to start transaction,
-     * then Thread # 2's query will have been blocked by java layer
-     * until Thread#1 ends transaction.
-     *
-     * @throws InterruptedException
-     */
-    @SmallTest
-    public void testExecSqlToStartAndEndTransaction() throws InterruptedException {
-        runExecSqlToStartAndEndTransaction("END");
-        // same as above, instead now do "COMMIT" or "ROLLBACK" instead of "END" transaction
-        runExecSqlToStartAndEndTransaction("COMMIT");
-        runExecSqlToStartAndEndTransaction("ROLLBACK");
-    }
-    private void runExecSqlToStartAndEndTransaction(String str) throws InterruptedException {
-        createTableAndClearCache();
-        // disable WAL just so queries and updates use the same database connection
-        mDatabase.disableWriteAheadLogging();
-        mDatabase.execSQL("BEGIN transaction");
-        // even though mDatabase.beginTransaction() is not called to start transaction,
-        // mDatabase connection should now be in transaction as a result of
-        // mDatabase.execSQL("BEGIN transaction")
-        // but mDatabase.mLock should not be held by any thread
-        assertTrue(mDatabase.inTransaction());
-        assertFalse(mDatabase.isDbLockedByCurrentThread());
-        assertFalse(mDatabase.isDbLockedByOtherThreads());
-        assertTrue(mDatabase.amIInTransaction());
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        assertTrue(mDatabase.inTransaction());
-        assertFalse(mDatabase.isDbLockedByCurrentThread());
-        assertFalse(mDatabase.isDbLockedByOtherThreads());
-        assertTrue(mDatabase.amIInTransaction());
-        Thread t = new Thread() {
-            @Override public void run() {
-                assertTrue(mDatabase.amIInTransaction());
-                assertEquals(999, DatabaseUtils.longForQuery(getDb(),
-                        "select j from " + TEST_TABLE + " WHERE i = 10", null));
-                assertTrue(getDb().inTransaction());
-                assertFalse(getDb().isDbLockedByCurrentThread());
-                assertFalse(getDb().isDbLockedByOtherThreads());
-                assertTrue(mDatabase.amIInTransaction());
-            }
-        };
-        t.start();
-        t.join();
-        assertTrue(mDatabase.amIInTransaction());
-        assertTrue(mDatabase.inTransaction());
-        assertFalse(mDatabase.isDbLockedByCurrentThread());
-        assertFalse(mDatabase.isDbLockedByOtherThreads());
-        mDatabase.execSQL(str);
-        assertFalse(mDatabase.amIInTransaction());
-        assertFalse(mDatabase.inTransaction());
-        assertFalse(mDatabase.isDbLockedByCurrentThread());
-        assertFalse(mDatabase.isDbLockedByOtherThreads());
-    }
-
-    /**
-     * test the following
-     * http://b/issue?id=2871037
-     *          Cursor cursor = db.query(...);
-     *          // with WAL enabled, the above uses a pooled database connection
-     *          db.beginTransaction()
-     *          try {
-     *            db.insert(......);
-     *            cursor.requery();
-     *            // since the cursor uses pooled database connection, the above requery
-     *            // will not return the results that were inserted above since the insert is
-     *            // done using main database connection AND the transaction is not committed yet.
-     *            // fix is to make the above cursor use the main database connection - and NOT
-     *            // the pooled database connection
-     *            db.setTransactionSuccessful()
-     *          } finally {
-     *            db.endTransaction()
-     *          }
-     *
-     * @throws InterruptedException
-     */
-    @SmallTest
-    public void testTransactionAndWalInterplay1() throws InterruptedException {
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        String sql = "select * from " + TEST_TABLE;
-        Cursor c = mDatabase.rawQuery(sql, null);
-        // should have 1 row in the table
-        assertEquals(1, c.getCount());
-        mDatabase.beginTransactionNonExclusive();
-        try {
-            mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(100, 9909);");
-            assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
-                    "select count(*) from " + TEST_TABLE, null));
-            // requery on the previously opened cursor
-            // cursor should now use the main database connection and see 2 rows
-            c.requery();
-            assertEquals(2, c.getCount());
-            mDatabase.setTransactionSuccessful();
-        } finally {
-            mDatabase.endTransaction();
-        }
-        c.close();
-
-        // do the same test but now do the requery in a separate thread.
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        final Cursor c1 = mDatabase.rawQuery("select count(*) from " + TEST_TABLE, null);
-        // should have 1 row in the table
-        assertEquals(1, c1.getCount());
-        mDatabase.beginTransactionNonExclusive();
-        try {
-            mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(100, 9909);");
-            assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
-                    "select count(*) from " + TEST_TABLE, null));
-            // query in a different thread. that causes the cursor to use a pooled connection
-            // and since this thread hasn't committed its changes, the cursor should still see only
-            // 1 row
-            Thread t = new Thread() {
-                @Override public void run() {
-                    c1.requery();
-                    assertEquals(1, c1.getCount());
-                }
-            };
-            t.start();
-            t.join();
-            // should be 2 rows now - including the the row inserted above
-            mDatabase.setTransactionSuccessful();
-        } finally {
-            mDatabase.endTransaction();
-        }
-        c1.close();
-    }
-
-    /**
-     * This test is same as {@link #testTransactionAndWalInterplay1()} except the following:
-     * instead of mDatabase.beginTransactionNonExclusive(), use execSQL("BEGIN transaction")
-     * and instead of mDatabase.endTransaction(), use execSQL("END");
-     */
-    @SmallTest
-    public void testTransactionAndWalInterplay2() throws InterruptedException {
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        String sql = "select * from " + TEST_TABLE;
-        Cursor c = mDatabase.rawQuery(sql, null);
-        // should have 1 row in the table
-        assertEquals(1, c.getCount());
-        mDatabase.execSQL("BEGIN transaction");
-        try {
-            mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(100, 9909);");
-            assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
-                    "select count(*) from " + TEST_TABLE, null));
-            // requery on the previously opened cursor
-            // cursor should now use the main database connection and see 2 rows
-            c.requery();
-            assertEquals(2, c.getCount());
-        } finally {
-            mDatabase.execSQL("commit;");
-        }
-        c.close();
-
-        // do the same test but now do the requery in a separate thread.
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        final Cursor c1 = mDatabase.rawQuery("select count(*) from " + TEST_TABLE, null);
-        // should have 1 row in the table
-        assertEquals(1, c1.getCount());
-        mDatabase.execSQL("BEGIN transaction");
-        try {
-            mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(100, 9909);");
-            assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
-                    "select count(*) from " + TEST_TABLE, null));
-            // query in a different thread. but since the transaction is started using
-            // execSQ() instead of beginTransaction(), cursor's query is considered part of
-            // the same transaction - and hence it should see the above inserted row
-            Thread t = new Thread() {
-                @Override public void run() {
-                    c1.requery();
-                    assertEquals(1, c1.getCount());
-                }
-            };
-            t.start();
-            t.join();
-            // should be 2 rows now - including the the row inserted above
-        } finally {
-            mDatabase.execSQL("commit");
-        }
-        c1.close();
-    }
-
-    /**
-     * This test is same as {@link #testTransactionAndWalInterplay2()} except the following:
-     * instead of committing the data, do rollback and make sure the data seen by the query
-     * within the transaction is now gone.
-     */
-    @SmallTest
-    public void testTransactionAndWalInterplay3() {
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        String sql = "select * from " + TEST_TABLE;
-        Cursor c = mDatabase.rawQuery(sql, null);
-        // should have 1 row in the table
-        assertEquals(1, c.getCount());
-        mDatabase.execSQL("BEGIN transaction");
-        try {
-            mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(100, 9909);");
-            assertEquals(2, DatabaseUtils.longForQuery(mDatabase,
-                    "select count(*) from " + TEST_TABLE, null));
-            // requery on the previously opened cursor
-            // cursor should now use the main database connection and see 2 rows
-            c.requery();
-            assertEquals(2, c.getCount());
-        } finally {
-            // rollback the change
-            mDatabase.execSQL("rollback;");
-        }
-        // since the change is rolled back, do the same query again and should now find only 1 row
-        c.requery();
-        assertEquals(1, c.getCount());
-        assertEquals(1, DatabaseUtils.longForQuery(mDatabase,
-                "select count(*) from " + TEST_TABLE, null));
-        c.close();
-    }
-
-    @SmallTest
-    public void testAttachDb() {
-        String newDb = "/sdcard/mydata.db";
-        File f = new File(newDb);
-        if (f.exists()) {
-            f.delete();
-        }
-        assertFalse(f.exists());
-        SQLiteDatabase db = SQLiteDatabase.openOrCreateDatabase(newDb, null);
-        db.execSQL("create table test1 (i int);");
-        db.execSQL("insert into test1 values(1);");
-        db.execSQL("insert into test1 values(11);");
-        Cursor c = null;
-        try {
-            c = db.rawQuery("select * from test1", null);
-            int count = c.getCount();
-            Log.i(TAG, "count: " + count);
-            assertEquals(2, count);
-        } finally {
-            c.close();
-            db.close();
-            c = null;
-        }
-
-        mDatabase.execSQL("attach database ? as newDb" , new String[]{newDb});
-        Cursor c1 = null;
-        try {
-            c1 = mDatabase.rawQuery("select * from newDb.test1", null);
-            assertEquals(2, c1.getCount());
-        } catch (Exception e) {
-            fail("unexpected exception: " + e.getMessage());
-        } finally {
-            if (c1 != null) {
-                c1.close();
-            }
-        }
-        List<Pair<String, String>> dbs = mDatabase.getAttachedDbs();
-        for (Pair<String, String> p: dbs) {
-            Log.i(TAG, "attached dbs: " + p.first + " : " + p.second);
-        }
-        assertEquals(2, dbs.size());
-     }
-
-    /**
-     * http://b/issue?id=2943028
-     * SQLiteOpenHelper maintains a Singleton even if it is in bad state.
-     */
-    @SmallTest
-    public void testCloseAndReopen() {
-        mDatabase.close();
-        TestOpenHelper helper = new TestOpenHelper(getContext(), DB_NAME, null,
-                CURRENT_DATABASE_VERSION, new DefaultDatabaseErrorHandler());
-        mDatabase = helper.getWritableDatabase();
-        createTableAndClearCache();
-        mDatabase.execSQL("INSERT into " + TEST_TABLE + " values(10, 999);");
-        Cursor c = mDatabase.query(TEST_TABLE, new String[]{"i", "j"}, null, null, null, null, null);
-        assertEquals(1, c.getCount());
-        c.close();
-        mDatabase.close();
-        assertFalse(mDatabase.isOpen());
-        mDatabase = helper.getReadableDatabase();
-        assertTrue(mDatabase.isOpen());
-        c = mDatabase.query(TEST_TABLE, new String[]{"i", "j"}, null, null, null, null, null);
-        assertEquals(1, c.getCount());
-        c.close();
-    }
-    private class TestOpenHelper extends SQLiteOpenHelper {
-        public TestOpenHelper(Context context, String name, CursorFactory factory, int version,
-                DatabaseErrorHandler errorHandler) {
-            super(context, name, factory, version, errorHandler);
-        }
-        @Override public void onCreate(SQLiteDatabase db) {}
-        @Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {}
-    }
-}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteStatementTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteStatementTest.java
deleted file mode 100644
index 955336a..0000000
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteStatementTest.java
+++ /dev/null
@@ -1,213 +0,0 @@
-/*
- * Copyright (C) 2006 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.database.sqlite;
-
-import android.content.Context;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.LargeTest;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.File;
-import java.util.Random;
-import java.util.concurrent.locks.ReentrantLock;
-
-public class SQLiteStatementTest extends AndroidTestCase {
-    private SQLiteDatabase mDatabase;
-    private File mDatabaseFile;
-
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
-        mDatabaseFile = new File(dbDir, "database_test.db");
-        if (mDatabaseFile.exists()) {
-            mDatabaseFile.delete();
-        }
-        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
-        assertNotNull(mDatabase);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mDatabase.close();
-        mDatabaseFile.delete();
-        super.tearDown();
-    }
-
-    /**
-     * Start 2 threads to repeatedly execute the above SQL statement.
-     * Even though 2 threads are executing the same SQL, they each should get their own copy of
-     * prepared SQL statement id and there SHOULD NOT be an error from sqlite or android.
-     * @throws InterruptedException thrown if the test threads started by this test are interrupted
-     */
-    @LargeTest
-    public void testUseOfSameSqlStatementBy2Threads() throws InterruptedException {
-        mDatabase.execSQL("CREATE TABLE test_pstmt (i INTEGER PRIMARY KEY, j text);");
-        final String stmt = "SELECT * FROM test_pstmt WHERE i = ?";
-        class RunStmtThread extends Thread {
-            @Override public void run() {
-                // do it enough times to make sure there are no corner cases going untested
-                for (int i = 0; i < 1000; i++) {
-                    SQLiteStatement s1 = mDatabase.compileStatement(stmt);
-                    s1.bindLong(1, i);
-                    s1.execute();
-                    s1.close();
-                 }
-            }
-        }
-        RunStmtThread t1 = new RunStmtThread();
-        t1.start();
-        RunStmtThread t2 = new RunStmtThread();
-        t2.start();
-         while (t1.isAlive() || t2.isAlive()) {
-             Thread.sleep(10);
-         }
-     }
-
-    /**
-     * A simple test: start 2 threads to repeatedly execute the same {@link SQLiteStatement}.
-     * The 2 threads take turns to use the {@link SQLiteStatement}; i.e., it is NOT in use
-     * by both the threads at the same time.
-     *
-     * @throws InterruptedException thrown if the test threads started by this test are interrupted
-     */
-    @LargeTest
-    public void testUseOfSameSqliteStatementBy2Threads() throws InterruptedException {
-        mDatabase.execSQL("CREATE TABLE test_pstmt (i INTEGER PRIMARY KEY, j text);");
-        final String stmt = "SELECT * FROM test_pstmt WHERE i = ?";
-        final SQLiteStatement s1 = mDatabase.compileStatement(stmt);
-        class RunStmtThread extends Thread {
-            @Override public void run() {
-                // do it enough times to make sure there are no corner cases going untested
-                for (int i = 0; i < 1000; i++) {
-                    lock();
-                    try {
-                        s1.bindLong(1, i);
-                        s1.execute();
-                    } finally {
-                        unlock();
-                    }
-                    Thread.yield();
-                }
-            }
-        }
-        RunStmtThread t1 = new RunStmtThread();
-        t1.start();
-        RunStmtThread t2 = new RunStmtThread();
-        t2.start();
-        while (t1.isAlive() || t2.isAlive()) {
-            Thread.sleep(10);
-        }
-    }
-    /** Synchronize on this when accessing the SqliteStatemet in the above */
-    private final ReentrantLock mLock = new ReentrantLock(true);
-    private void lock() {
-        mLock.lock();
-    }
-    private void unlock() {
-        mLock.unlock();
-    }
-
-    /**
-     * Tests the following: a {@link SQLiteStatement} object should not refer to a
-     * pre-compiled SQL statement id except in during the period of binding the arguments
-     * and executing the SQL statement.
-     */
-    @LargeTest
-    public void testReferenceToPrecompiledStatementId() {
-        mDatabase.execSQL("create table t (i int, j text);");
-        verifyReferenceToPrecompiledStatementId(false);
-        verifyReferenceToPrecompiledStatementId(true);
-
-        // a small stress test to make sure there are no side effects of
-        // the acquire & release of pre-compiled statement id by SQLiteStatement object.
-        for (int i = 0; i < 100; i++) {
-            verifyReferenceToPrecompiledStatementId(false);
-            verifyReferenceToPrecompiledStatementId(true);
-        }
-    }
-
-    @SuppressWarnings("deprecation")
-    private void verifyReferenceToPrecompiledStatementId(boolean wal) {
-        if (wal) {
-            mDatabase.enableWriteAheadLogging();
-        } else {
-            mDatabase.disableWriteAheadLogging();
-        }
-        // test with INSERT statement - doesn't use connection pool, if WAL is set
-        SQLiteStatement stmt = mDatabase.compileStatement("insert into t values(?,?);");
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        // sql statement should not be compiled yet
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        int colValue = new Random().nextInt();
-        stmt.bindLong(1, colValue);
-        // verify that the sql statement is still not compiled
-        assertEquals(0, stmt.getSqlStatementId());
-        // should still be using the mDatabase connection - verify
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        stmt.bindString(2, "blah" + colValue);
-        // verify that the sql statement is still not compiled
-        assertEquals(0, stmt.getSqlStatementId());
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        stmt.executeInsert();
-        // now that the statement is executed, pre-compiled statement should be released
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        stmt.close();
-        // pre-compiled SQL statement should still remain released from this object
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        // but the database handle should still be the same
-        assertEquals(mDatabase, stmt.mDatabase);
-
-        // test with a SELECT statement - uses connection pool if WAL is set
-        stmt = mDatabase.compileStatement("select i from t where j=?;");
-        // sql statement should not be compiled yet
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        stmt.bindString(1, "blah" + colValue);
-        // verify that the sql statement is still not compiled
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        // execute the statement
-        Long l = stmt.simpleQueryForLong();
-        assertEquals(colValue, l.intValue());
-        // now that the statement is executed, pre-compiled statement should be released
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-        stmt.close();
-        // pre-compiled SQL statement should still remain released from this object
-        assertEquals(0, stmt.nStatement);
-        assertEquals(0, stmt.getSqlStatementId());
-        // but the database handle should still remain attached to the statement
-        assertEquals(mDatabase.mNativeHandle, stmt.nHandle);
-        assertEquals(mDatabase, stmt.mDatabase);
-    }
-}
diff --git a/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java b/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java
deleted file mode 100644
index cd2005d..0000000
--- a/core/tests/coretests/src/android/database/sqlite/SQLiteUnfinalizedExceptionTest.java
+++ /dev/null
@@ -1,81 +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 android.database.sqlite;
-
-import android.content.Context;
-import android.database.sqlite.SQLiteDatabaseTest.ClassToTestSqlCompilationAndCaching;
-import android.test.AndroidTestCase;
-import android.test.suitebuilder.annotation.SmallTest;
-
-import java.io.File;
-
-public class SQLiteUnfinalizedExceptionTest extends AndroidTestCase {
-    private SQLiteDatabase mDatabase;
-    private File mDatabaseFile;
-    private static final String TABLE_NAME = "testCursor";
-    @Override
-    protected void setUp() throws Exception {
-        super.setUp();
-
-        File dbDir = getContext().getDir(this.getClass().getName(), Context.MODE_PRIVATE);
-        mDatabaseFile = new File(dbDir, "UnfinalizedExceptionTest.db");
-        if (mDatabaseFile.exists()) {
-            mDatabaseFile.delete();
-        }
-        mDatabase = SQLiteDatabase.openOrCreateDatabase(mDatabaseFile.getPath(), null);
-        assertNotNull(mDatabase);
-    }
-
-    @Override
-    protected void tearDown() throws Exception {
-        mDatabase.close();
-        mDatabaseFile.delete();
-        super.tearDown();
-    }
-
-    @SmallTest
-    public void testUnfinalizedExceptionNotExcpected() {
-        mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (i int, j int);");
-        // the above statement should be in SQLiteDatabase.mPrograms
-        // and should automatically be finalized when database is closed
-        mDatabase.lock();
-        try {
-            mDatabase.closeDatabase();
-        } finally {
-            mDatabase.unlock();
-        }
-    }
-
-    @SmallTest
-    public void testUnfinalizedException() {
-        mDatabase.execSQL("CREATE TABLE " + TABLE_NAME + " (i int, j int);");
-        mDatabase.lock();
-        mDatabase.closePendingStatements(); // clears the above from finalizer queue in mdatabase
-        mDatabase.unlock();
-        ClassToTestSqlCompilationAndCaching.create(mDatabase, "select * from "  + TABLE_NAME);
-        // since the above is NOT closed, closing database should fail
-        mDatabase.lock();
-        try {
-            mDatabase.closeDatabase();
-            fail("exception expected");
-        } catch (SQLiteUnfinalizedObjectsException e) {
-            // expected
-        } finally {
-            mDatabase.unlock();
-        }
-    }
-}
diff --git a/docs/html/design/get-started/principles.html b/docs/html/design/get-started/principles.html
index c564e5c..0d9ef20 100644
--- a/docs/html/design/get-started/principles.html
+++ b/docs/html/design/get-started/principles.html
@@ -147,8 +147,9 @@
   <div class="layout-content-col span-7">
 
 <h4>Let me make it mine</h4>
-<p>Let people add a personal touch because it helps them feel at home and in control. Think about
-subtle ways to offer personalization while providing sensible and beautiful default functionality.</p>
+<p>People love to add personal touches because it helps them feel at home and in control. Provide
+sensible, beautiful defaults, but also consider fun, optional customizations that don't hinder
+primary tasks.</p>
 
   </div>
   <div class="layout-content-col span-6">
diff --git a/docs/html/design/static/content/principles_decide_for_me.png b/docs/html/design/static/content/principles_decide_for_me.png
index 65911bc..2d8b883 100644
--- a/docs/html/design/static/content/principles_decide_for_me.png
+++ b/docs/html/design/static/content/principles_decide_for_me.png
Binary files differ
diff --git a/docs/html/design/static/content/principles_make_it_mine.png b/docs/html/design/static/content/principles_make_it_mine.png
index 3b63238..683a0b7 100644
--- a/docs/html/design/static/content/principles_make_it_mine.png
+++ b/docs/html/design/static/content/principles_make_it_mine.png
Binary files differ
diff --git a/docs/html/design/static/default.css b/docs/html/design/static/default.css
index 20fefad..42ab527 100644
--- a/docs/html/design/static/default.css
+++ b/docs/html/design/static/default.css
@@ -279,8 +279,7 @@
       background: rgba(0, 0, 0, 0.03); }
   #nav #back-dac-section {
     padding: 10px;
-    border-top: 1px solid #ddd;
-    background: transparent url(open_new_page.png) no-repeat scroll 139px 9px; }
+    border-top: 1px solid #ddd; }
     #nav #back-dac-section a {
       color: #333333;
       font-weight: 500;
@@ -569,4 +568,4 @@
     height: 12px;
     margin-right: 8px; }
   .video-instructions:after {
-    content: 'Click or move mouse over screenshot to replay movie.'; }
+    content: 'Click to replay movie.'; }
diff --git a/docs/html/design/static/default.js b/docs/html/design/static/default.js
index 26848e6..6721ab8 100644
--- a/docs/html/design/static/default.js
+++ b/docs/html/design/static/default.js
@@ -125,7 +125,8 @@
   });
 
   // Set up play-on-hover <video> tags.
-  $('video.play-on-hover').bind('mouseenter click', function(){
+  $('video.play-on-hover').bind('click', function(){
+    $(this).get(0).load(); // in case the video isn't seekable
     $(this).get(0).play();
   });
 
diff --git a/docs/html/guide/topics/manifest/uses-sdk-element.jd b/docs/html/guide/topics/manifest/uses-sdk-element.jd
index b371f34..99c91f6 100644
--- a/docs/html/guide/topics/manifest/uses-sdk-element.jd
+++ b/docs/html/guide/topics/manifest/uses-sdk-element.jd
@@ -60,7 +60,7 @@
   attribute, the system assumes a default value of "1", which indicates that your
   application is compatible with all versions of Android. If your application is
   <em>not</em> compatible with all versions (for instance, it uses APIs introduced
-  in API Level 3) and you have not declared the proper <code>android:minSdkVersion</code>,
+  in API Level 3) and you have not declared the proper <code>minSdkVersion</code>,
   then when installed on a system with an API Level less than 3, the application
   will crash during runtime when attempting to access the unavailable APIs. For
   this reason, be certain to declare the appropriate API Level in the
@@ -68,18 +68,32 @@
   </dd>
 
   <dt><a name="target"></a>{@code android:targetSdkVersion}</dt>
-  <dd>An integer designating the API Level that the application is targetting.
+  <dd>An integer designating the API Level that the application targets. If not set, the default
+value equals that given to {@code minSdkVersion}.
 
-  <p>With this attribute set, the application says that it is able to run on
-  older versions (down to {@code minSdkVersion}), but was explicitly tested to
-  work with the version specified here. Specifying this target version allows the
-  platform to disable compatibility settings that are not required for the target
-  version (which may otherwise be turned on in order to maintain
-  forward-compatibility) or enable newer features that are not available to older
-  applications. This does not mean that you can program different features for
-  different versions of the platform&mdash;it simply informs the platform that you
-  have tested against the target version and the platform should not perform any
-  extra work to maintain forward-compatibility with the target version.</p>
+  <p>This attribute informs the system that you have tested against the target version and the
+system should not enable any compatibility behaviors to maintain your app's forward-compatibility
+with the target version. The application is still able to run on older versions (down to {@code
+minSdkVersion}).</p>
+
+  <p>As Android evolves with each new version, some behaviors and even appearances might change.
+However, if the API level of the platform is higher than the version declared by your app's {@code
+targetSdkVersion}, the system may enable compatibility behaviors to ensure that your app
+continues to work the way you expect. You can disable such compatibility
+behaviors by specifying {@code targetSdkVersion} to match the API
+level of the platform on which it's running. For example, setting this value to "11" or higher
+allows the system to apply a new default theme (Holo) to your app when running on Android 3.0 or
+higher and also disables <a href="{@docRoot}guide/practices/screen-compat-mode.html">screen
+compatibility mode</a> when running on larger screens (because support for API level 11 implicitly
+supports larger screens).</p>
+
+  <p>There are many compatibility behaviors that the system may enable based on the value you set
+for this attribute. Several of these behaviors are described by the corresponding platform versions
+in the {@link android.os.Build.VERSION_CODES} reference.</p>
+
+  <p>To maintain your application along with each Android release, you should increase
+the value of this attribute to match the latest API level, then thoroughly test your application on
+the corresponding platform version.</p>
 
   <p>Introduced in: API Level 4</p>
   </dd>
@@ -89,25 +103,25 @@
   designed to run. 
 
   <p>In Android 1.5, 1.6, 2.0, and 2.0.1, the system checks the value of this
-  attribute when installing an application and when revalidating the application
+  attribute when installing an application and when re-validating the application
   after a system update. In either case, if the application's
-  <code>android:maxSdkVersion</code> attribute is lower than the API Level used by
+  <code>maxSdkVersion</code> attribute is lower than the API Level used by
   the system itself, then the system will not allow the application to be
-  installed. In the case of revalidation after system update, this effectively
+  installed. In the case of re-validation after system update, this effectively
   removes your application from the device.
 
   <p>To illustrate how this attribute can affect your application after system
   updates, consider the following example: </p>
 
-  <p>An application declaring <code>android:maxSdkVersion="5"</code> in its
+  <p>An application declaring <code>maxSdkVersion="5"</code> in its
   manifest is published on Android Market. A user whose device is running Android
   1.6 (API Level 4) downloads and installs the app. After a few weeks, the user
   receives an over-the-air system update to Android 2.0 (API Level 5). After the
   update is installed, the system checks the application's
-  <code>android:maxSdkVersion</code> and successfully revalidates it. The
+  <code>maxSdkVersion</code> and successfully re-validates it. The
   application functions as normal. However, some time later, the device receives
   another system update, this time to Android 2.0.1 (API Level 6). After the
-  update, the system can no longer revalidate the application because the system's
+  update, the system can no longer re-validate the application because the system's
   own API Level (6) is now higher than the maximum supported by the application
   (5). The system prevents the application from being visible to the user, in
   effect removing it from the device.</p>
@@ -120,7 +134,7 @@
   provided it uses only standard APIs and follows development best practices.
   Second, note that in some cases, declaring the attribute can <strong>result in
   your application being removed from users' devices after a system
-  update</strong> to a higher API Level. Most devices on which your appplication
+  update</strong> to a higher API Level. Most devices on which your application
   is likely to be installed will receive periodic system updates over the air, so
   you should consider their effect on your application before setting this
   attribute.</p>
@@ -128,8 +142,8 @@
   <p style="margin-bottom:1em;">Introduced in: API Level 4</p>
 
   <div class="special">Future versions of Android (beyond Android 2.0.1) will no
-longer check or enforce the <code>android:maxSdkVersion</code> attribute during
-installation or revalidation. Android Market will continue to use the attribute
+longer check or enforce the <code>maxSdkVersion</code> attribute during
+installation or re-validation. Android Market will continue to use the attribute
 as a filter, however, when presenting users with applications available for
 download. </div>
   </dd>
diff --git a/docs/html/index.jd b/docs/html/index.jd
index 53c59e7..9197b5d 100644
--- a/docs/html/index.jd
+++ b/docs/html/index.jd
@@ -11,8 +11,10 @@
                             </div><!-- end homeTitle -->
                             <div id="announcement-block">
                             <!-- total max width is 520px -->
+                                <a href="{@docRoot}design/index.html">
                                   <img src="{@docRoot}images/home/android-design.png"
 alt="Android Design" width="160px" style="padding:10px 33px 5px"/>
+                                </a>
                                   <div id="announcement" style="width:275px">
     <p>Introducing <b>Android Design</b>: The place to learn about principles, building blocks, and patterns
       for creating world-class Android user interfaces. Whether you're a UI professional or a developer
diff --git a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
index 46f4c39..c9b1673 100644
--- a/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
+++ b/packages/SystemUI/res/layout-sw600dp/status_bar_notification_panel_title.xml
@@ -25,120 +25,167 @@
     android:background="@drawable/notify_panel_clock_bg"
     >
 
-    <LinearLayout
+    <TableLayout
         android:id="@+id/icons"
-        android:layout_width="wrap_content"
+        android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:layout_alignParentLeft="true"
         android:layout_alignParentBottom="true"
-        android:baselineAlignedChildIndex="0"
         android:layout_marginLeft="16dp"
         android:layout_marginTop="16dp"
         android:layout_marginBottom="16dp"
+        android:shrinkColumns="2,4"
+        android:stretchColumns="7"
         >
+        <TableRow>
 
-        <ImageView
-            android:id="@+id/bluetooth"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:scaleType="centerInside"
-            android:baseline="18dp"
-            android:visibility="gone"
-            android:contentDescription="@null"
-            />
-
-        <FrameLayout
-            android:id="@+id/netwerk"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:layout_marginRight="4dp"
-            >
-
-            <ImageView
-                android:id="@+id/network_signal"
+            <!-- to keep the column ids stable we wrap disappearing views in
+                 frames -->
+            <FrameLayout
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
-                android:contentDescription="@null"
+                >
+                <ImageView
+                    android:id="@+id/bluetooth"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:scaleType="centerInside"
+                    android:visibility="gone"
+                    android:contentDescription="@null"
+                    android:layout_gravity="center_vertical"
+                    />
+            </FrameLayout>
+
+            <!-- mobile data -->
+            <FrameLayout
+                android:id="@+id/mobile_icon"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:paddingRight="4dp"
+                android:layout_gravity="center_vertical"
+                >
+
+                <ImageView
+                    android:id="@+id/mobile_signal"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    />
+
+                <ImageView
+                    android:id="@+id/mobile_type"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    />
+
+            </FrameLayout>
+            <TextView
+                android:id="@+id/mobile_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_gravity="left|center_vertical"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="8dp"
+                android:layout_weight="1"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:text="@string/status_bar_settings_settings_button"
+                />
+
+            <!-- wifi -->
+            <FrameLayout
+                android:id="@+id/wifi_icon"
+                android:layout_height="wrap_content"
+                android:layout_width="wrap_content"
+                android:paddingRight="4dp"
+                android:layout_gravity="center_vertical"
+                >
+
+                <ImageView
+                    android:id="@+id/wifi_signal"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    />
+
+                <ImageView
+                    android:id="@+id/wifi_direction"
+                    android:layout_height="wrap_content"
+                    android:layout_width="wrap_content"
+                    android:contentDescription="@null"
+                    />
+
+            </FrameLayout>
+            <TextView
+                android:id="@+id/wifi_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_gravity="left|center_vertical"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:paddingRight="8dp"
+                android:singleLine="true"
+                android:ellipsize="end"
+                android:text="@string/status_bar_settings_settings_button"
                 />
 
             <ImageView
-                android:id="@+id/network_type"
+                android:id="@+id/battery"
                 android:layout_height="wrap_content"
                 android:layout_width="wrap_content"
+                android:scaleType="centerInside"
+                android:layout_gravity="center_vertical"
+                android:layout_alignBaseline="@id/wifi_signal"
+                android:paddingLeft="8dp"
+                android:paddingRight="8dp"
                 android:contentDescription="@null"
                 />
 
-            <ImageView
-                android:id="@+id/network_direction"
+            <TextView
+                android:id="@+id/battery_text"
+                style="@style/StatusBarNotificationText"
+                android:layout_width="56dp"
                 android:layout_height="wrap_content"
-                android:layout_width="wrap_content"
-                android:contentDescription="@null"
+                android:layout_gravity="left|center_vertical"
+                android:paddingRight="8dp"
+                android:singleLine="true"
+                android:text="@string/status_bar_settings_settings_button"
                 />
 
-        </FrameLayout>
-            
-        <TextView
-            android:id="@+id/network_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/netwerk"
-            android:layout_marginRight="8dp"
-            android:layout_alignBaseline="@id/network_signal"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
+            <!-- this will stretch to eat up available space -->
+            <View
+                android:layout_width="0dp"
+                android:layout_height="0dp"
+                />
 
-        <ImageView
-            android:id="@+id/battery"
-            android:layout_height="wrap_content"
-            android:layout_width="wrap_content"
-            android:scaleType="centerInside"
-            android:layout_toRightOf="@id/network_text"
-            android:layout_alignBaseline="@id/network_signal"
-            android:baseline="18dp"
-            android:layout_marginLeft="8dp"
-            android:layout_marginRight="8dp"
-            android:contentDescription="@null"
-            />
+            <FrameLayout
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_gravity="center_vertical"
+                >
 
-        <TextView
-            android:id="@+id/battery_text"
-            style="@style/StatusBarNotificationText"
-            android:layout_width="56dp"
-            android:layout_height="wrap_content"
-            android:layout_toRightOf="@id/battery"
-            android:layout_alignBaseline="@id/battery"
-            android:layout_marginRight="8dp"
-            android:singleLine="true"
-            android:text="@string/status_bar_settings_settings_button"
-            />
-    </LinearLayout>
+                <ImageView
+                    android:id="@+id/settings_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingRight="16dp"
+                    android:src="@drawable/ic_sysbar_quicksettings"
+                    android:contentDescription="@string/accessibility_settings_button"
+                    />
 
-    <ImageView
-        android:id="@+id/settings_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBaseline="@id/icons"
-        android:layout_alignParentRight="true"
-        android:paddingRight="16dp"
-        android:src="@drawable/ic_sysbar_quicksettings"
-        android:baseline="21dp"
-        android:contentDescription="@string/accessibility_settings_button"
-        />
+                <ImageView
+                    android:id="@+id/notification_button"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingRight="16dp"
+                    android:src="@drawable/ic_notification_open"
+                    android:visibility="invisible"
+                    android:contentDescription="@string/accessibility_notifications_button"
+                    />
+            </FrameLayout>
 
-    <ImageView
-        android:id="@+id/notification_button"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:layout_alignBaseline="@id/icons"
-        android:layout_alignParentRight="true"
-        android:paddingRight="16dp"
-        android:src="@drawable/ic_notification_open"
-        android:baseline="21dp"
-        android:visibility="invisible"
-        android:contentDescription="@string/accessibility_notifications_button"
-        />
+        </TableRow>
+    </TableLayout>
 
     <com.android.systemui.statusbar.tablet.HoloClock
         android:id="@+id/clock"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
index 135a04c..d9114a5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/NetworkController.java
@@ -135,7 +135,9 @@
     ArrayList<ImageView> mWimaxIconViews = new ArrayList<ImageView>();
     ArrayList<ImageView> mCombinedSignalIconViews = new ArrayList<ImageView>();
     ArrayList<ImageView> mDataTypeIconViews = new ArrayList<ImageView>();
-    ArrayList<TextView> mLabelViews = new ArrayList<TextView>();
+    ArrayList<TextView> mCombinedLabelViews = new ArrayList<TextView>();
+    ArrayList<TextView> mMobileLabelViews = new ArrayList<TextView>();
+    ArrayList<TextView> mWifiLabelViews = new ArrayList<TextView>();
     ArrayList<SignalCluster> mSignalClusters = new ArrayList<SignalCluster>();
     int mLastPhoneSignalIconId = -1;
     int mLastDataDirectionIconId = -1;
@@ -144,7 +146,7 @@
     int mLastWimaxIconId = -1;
     int mLastCombinedSignalIconId = -1;
     int mLastDataTypeIconId = -1;
-    String mLastLabel = "";
+    String mLastCombinedLabel = "";
 
     private boolean mHasMobileDataFeature;
 
@@ -257,8 +259,16 @@
         mDataTypeIconViews.add(v);
     }
 
-    public void addLabelView(TextView v) {
-        mLabelViews.add(v);
+    public void addCombinedLabelView(TextView v) {
+        mCombinedLabelViews.add(v);
+    }
+
+    public void addMobileLabelView(TextView v) {
+        mMobileLabelViews.add(v);
+    }
+
+    public void addWifiLabelView(TextView v) {
+        mWifiLabelViews.add(v);
     }
 
     public void addSignalCluster(SignalCluster cluster) {
@@ -873,11 +883,16 @@
 
         int combinedSignalIconId = 0;
         int combinedActivityIconId = 0;
-        String label = "";
+        String combinedLabel = "";
+        String wifiLabel = "";
+        String mobileLabel = "";
         int N;
 
         if (mDataConnected) {
-            label = mNetworkName;
+            mobileLabel = mNetworkName;
+            if (DEBUG) {
+                mobileLabel += "yyyyYYYYyyyyYYYY";
+            }
             combinedSignalIconId = mDataSignalIconId;
             switch (mDataActivity) {
                 case TelephonyManager.DATA_ACTIVITY_IN:
@@ -894,6 +909,7 @@
                     break;
             }
 
+            combinedLabel = mobileLabel;
             combinedActivityIconId = mMobileActivityIconId;
             combinedSignalIconId = mDataSignalIconId; // set by updateDataIcon()
             mContentDescriptionCombinedSignal = mContentDescriptionDataType;
@@ -901,10 +917,13 @@
 
         if (mWifiConnected) {
             if (mWifiSsid == null) {
-                label = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
+                wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_wifi_nossid);
                 mWifiActivityIconId = 0; // no wifis, no bits
             } else {
-                label = mWifiSsid;
+                wifiLabel = mWifiSsid;
+                if (DEBUG) {
+                    wifiLabel += "xxxxXXXXxxxxXXXX";
+                }
                 switch (mWifiActivity) {
                     case WifiManager.DATA_ACTIVITY_IN:
                         mWifiActivityIconId = R.drawable.stat_sys_wifi_in;
@@ -922,12 +941,13 @@
             }
 
             combinedActivityIconId = mWifiActivityIconId;
+            combinedLabel = wifiLabel;
             combinedSignalIconId = mWifiIconId; // set by updateWifiIcons()
             mContentDescriptionCombinedSignal = mContentDescriptionWifi;
         }
 
         if (mBluetoothTethered) {
-            label = mContext.getString(R.string.bluetooth_tethered);
+            combinedLabel = mContext.getString(R.string.bluetooth_tethered);
             combinedSignalIconId = mBluetoothTetherIconId;
             mContentDescriptionCombinedSignal = mContext.getString(
                     R.string.accessibility_bluetooth_tether);
@@ -945,7 +965,8 @@
 
             // combined values from connected wifi take precedence over airplane mode
             if (!mWifiConnected) {
-                label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+                wifiLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+                combinedLabel = wifiLabel;
                 mContentDescriptionCombinedSignal = mContentDescriptionPhoneSignal;
                 combinedSignalIconId = mDataSignalIconId;
             }
@@ -953,7 +974,7 @@
         else if (!mDataConnected && !mWifiConnected && !mBluetoothTethered && !mWimaxConnected) {
             // pretty much totally disconnected
 
-            label = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
+            combinedLabel = context.getString(R.string.status_bar_settings_signal_meter_disconnected);
             // On devices without mobile radios, we want to show the wifi icon
             combinedSignalIconId =
                 mHasMobileDataFeature ? mDataSignalIconId : mWifiIconId;
@@ -1028,7 +1049,7 @@
             for (int i=0; i<N; i++) {
                 final ImageView v = mWifiIconViews.get(i);
                 if (mWifiIconId == 0) {
-                    v.setVisibility(View.INVISIBLE);
+                    v.setVisibility(View.GONE);
                 } else {
                     v.setVisibility(View.VISIBLE);
                     v.setImageResource(mWifiIconId);
@@ -1044,7 +1065,7 @@
             for (int i=0; i<N; i++) {
                 final ImageView v = mWimaxIconViews.get(i);
                 if (mWimaxIconId == 0) {
-                    v.setVisibility(View.INVISIBLE);
+                    v.setVisibility(View.GONE);
                 } else {
                     v.setVisibility(View.VISIBLE);
                     v.setImageResource(mWimaxIconId);
@@ -1070,7 +1091,7 @@
             for (int i=0; i<N; i++) {
                 final ImageView v = mDataTypeIconViews.get(i);
                 if (mDataTypeIconId == 0) {
-                    v.setVisibility(View.INVISIBLE);
+                    v.setVisibility(View.GONE);
                 } else {
                     v.setVisibility(View.VISIBLE);
                     v.setImageResource(mDataTypeIconId);
@@ -1089,7 +1110,7 @@
             for (int i=0; i<N; i++) {
                 final ImageView v = mDataDirectionOverlayIconViews.get(i);
                 if (combinedActivityIconId == 0) {
-                    v.setVisibility(View.INVISIBLE);
+                    v.setVisibility(View.GONE);
                 } else {
                     v.setVisibility(View.VISIBLE);
                     v.setImageResource(combinedActivityIconId);
@@ -1098,15 +1119,29 @@
             }
         }
 
-        // the label in the notification panel
-        if (!mLastLabel.equals(label)) {
-            mLastLabel = label;
-            N = mLabelViews.size();
+        // the combinedLabel in the notification panel
+        if (!mLastCombinedLabel.equals(combinedLabel)) {
+            mLastCombinedLabel = combinedLabel;
+            N = mCombinedLabelViews.size();
             for (int i=0; i<N; i++) {
-                TextView v = mLabelViews.get(i);
-                v.setText(label);
+                TextView v = mCombinedLabelViews.get(i);
+                v.setText(combinedLabel);
             }
         }
+
+        // wifi label
+        N = mWifiLabelViews.size();
+        for (int i=0; i<N; i++) {
+            TextView v = mWifiLabelViews.get(i);
+            v.setText(wifiLabel);
+        }
+        
+        // mobile label
+        N = mMobileLabelViews.size();
+        for (int i=0; i<N; i++) {
+            TextView v = mMobileLabelViews.get(i);
+            v.setText(mobileLabel);
+        }
     }
 
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
@@ -1220,8 +1255,8 @@
         pw.print(Integer.toHexString(mLastDataTypeIconId));
         pw.print("/");
         pw.println(getResourceName(mLastDataTypeIconId));
-        pw.print("  mLastLabel=");
-        pw.print(mLastLabel);
+        pw.print("  mLastCombinedLabel=");
+        pw.print(mLastCombinedLabel);
         pw.println("");
     }
 
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
index 510fd3b..8e58649 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/NotificationPanel.java
@@ -316,8 +316,8 @@
 
     public void updatePanelModeButtons() {
         final boolean settingsVisible = (mSettingsView != null);
-        mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.INVISIBLE);
-        mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.INVISIBLE);
+        mSettingsButton.setVisibility(!settingsVisible ? View.VISIBLE : View.GONE);
+        mNotificationButton.setVisibility(settingsVisible ? View.VISIBLE : View.GONE);
     }
 
     public boolean isInContentArea(int x, int y) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
index 9919d825..6287408 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/tablet/TabletStatusBar.java
@@ -222,11 +222,6 @@
 
         // network icons: either a combo icon that switches between mobile and data, or distinct
         // mobile and data icons
-        final ImageView comboRSSI = 
-                (ImageView)mNotificationPanel.findViewById(R.id.network_signal);
-        if (comboRSSI != null) {
-            mNetworkController.addCombinedSignalIconView(comboRSSI);
-        }
         final ImageView mobileRSSI = 
                 (ImageView)mNotificationPanel.findViewById(R.id.mobile_signal);
         if (mobileRSSI != null) {
@@ -237,14 +232,14 @@
         if (wifiRSSI != null) {
             mNetworkController.addWifiIconView(wifiRSSI);
         }
+        mNetworkController.addWifiLabelView(
+                (TextView)mNotificationPanel.findViewById(R.id.wifi_text));
 
         mNetworkController.addDataTypeIconView(
-                (ImageView)mNotificationPanel.findViewById(R.id.network_type));
-        mNetworkController.addDataDirectionOverlayIconView(
-                (ImageView)mNotificationPanel.findViewById(R.id.network_direction));
-        mNetworkController.addLabelView(
-                (TextView)mNotificationPanel.findViewById(R.id.network_text));
-        mNetworkController.addLabelView(
+                (ImageView)mNotificationPanel.findViewById(R.id.mobile_type));
+        mNetworkController.addMobileLabelView(
+                (TextView)mNotificationPanel.findViewById(R.id.mobile_text));
+        mNetworkController.addCombinedLabelView(
                 (TextView)mBarContents.findViewById(R.id.network_text));
 
         mStatusBarView.setIgnoreChildren(0, mNotificationTrigger, mNotificationPanel);
diff --git a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
index 1d6f39a..91ab053 100644
--- a/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
+++ b/policy/src/com/android/internal/policy/impl/KeyguardUpdateMonitor.java
@@ -585,8 +585,7 @@
      * through mHandler, this *must* be called from the UI thread.
      */
     public void reportSimUnlocked() {
-        mSimState = IccCard.State.READY;
-        handleSimStateChange(new SimArgs(mSimState));
+        handleSimStateChange(new SimArgs(IccCard.State.READY));
     }
 
     public boolean isKeyguardBypassEnabled() {
diff --git a/services/java/com/android/server/connectivity/Vpn.java b/services/java/com/android/server/connectivity/Vpn.java
index efa05ba..c4f9ce1 100644
--- a/services/java/com/android/server/connectivity/Vpn.java
+++ b/services/java/com/android/server/connectivity/Vpn.java
@@ -322,7 +322,7 @@
                     .setContentTitle(title)
                     .setContentText(text)
                     .setContentIntent(VpnConfig.getIntentForStatusPanel(mContext, config))
-                    .setDefaults(Notification.DEFAULT_ALL)
+                    .setDefaults(0)
                     .setOngoing(true)
                     .getNotification();
             nm.notify(R.drawable.vpn_connected, notification);
