diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
index 560f780..7d41dd5 100644
--- a/samples/NotePad/AndroidManifest.xml
+++ b/samples/NotePad/AndroidManifest.xml
@@ -1,82 +1,39 @@
 <?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2010 The Android Open Source Project
+<!-- 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
+     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
+          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.
+     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.
 -->
 
-<!--
-     The manifest declares information about this Android application that is of
-     interest to the system and to other applications.
-     The namespace  attribute brings in the Android platform namespace. The package name is
-     an Android identifier for the application. It uses names in the Java package id format,
-     but is not dependent on or linked to any of the Java package names in the application.
-     It must be unique. If you use this manifest as part of your own application, you must
-     change the name prefix from "com.example." to a domain that you own or control.
+<!-- Declare the contents of this Android application.  The namespace
+     attribute brings in the Android platform namespace, and the package
+     supplies a unique name for the application.  When writing your
+     own application, the package name must be changed from "com.example.*"
+     to come from a domain that you own or have control over. -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.example.android.notepad"
+>
+    <application android:icon="@drawable/app_notes"
+        android:label="@string/app_name"
+    >
+        <provider android:name="NotePadProvider"
+            android:authorities="com.google.provider.NotePad"
+        />
 
--->
-    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-        package="com.example.android.notepad"
-        android:versionCode="1"
-        android:versionName="1.0">
-
-    <!--
-        Declares the attributes of the application.
-        The icon and label are displayed in the Launcher and in
-        other utilities that list applications.
-    -->
-    <application
-        android:icon="@drawable/app_notes"
-        android:label="@string/app_name" >
-
-    <!--
-        Declares the content provider offered by this application. The name is an
-        identifier. The authorities attribute is stored by the Android system in a global
-        table, along with a handle to the current instance of the provider.
-        Clients can then link to the provider through the global map by providing
-        the authority string to Android.
-    -->
-
-        <provider
-            android:name="NotePadProvider"
-            android:authorities="com.example.android.notepad.NotePad" />
-
-        <!--
-            Declares the NotesList activity, and gives it a name and a label.
-            The intent filters determine the types of intents that this activity will see.
-            The NotesList activity displays notes and returns single notes instances to
-            other activities.
-          -->
-        <activity
-            android:name="NotesList"
-            android:label="@string/title_notes_list">
-            <!--
-                Defines the main entry point into NotePad (MAIN), which doesn't
-                require any additional information. LAUNCHER tells launchers to display this
-                Activity.
-             -->
+        <activity android:name="NotesList" android:label="@string/title_notes_list">
             <intent-filter>
                 <action android:name="android.intent.action.MAIN" />
                 <category android:name="android.intent.category.LAUNCHER" />
             </intent-filter>
-            <!--
-                Defines actions the Activity can do on a directory of notes.
-                It allows the user to view a list of notes, edit a list of notes, or pick one
-                of the notes. The intent's MIME type must match the MIME type specified by the
-                <data> element. That element specifies a cursor of data containing
-                vnd.google.note objects (defined in this app).
-                Notice that all intent filters that don't specify MAIN must specify
-                DEFAULT as a category
-             -->
             <intent-filter>
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.EDIT" />
@@ -84,11 +41,6 @@
                 <category android:name="android.intent.category.DEFAULT" />
                 <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
             </intent-filter>
-            <!--
-                Defines an action the Activity can do for a single note. If the action is
-                GET_CONTENT, then the Activity can return a cursor containing at most 1
-                note object (an item) identified as a vnd.google.note item.
-             -->
             <intent-filter>
                 <action android:name="android.intent.action.GET_CONTENT" />
                 <category android:name="android.intent.category.DEFAULT" />
@@ -96,26 +48,14 @@
             </intent-filter>
         </activity>
 
-        <!--
-             Defines the NoteEditor activity. This activity edits or displays a single note.
-             The screen orientation displayed by this activity depends on the device orientation
-             (screenOrientation).
-             The activity uses a light theme (android:theme)
-             When the keyboard is closed (or hidden) or the device orientation changes, the
-             Activity will handle it. The Activity does not restart, but onConfigurationChanged() is
-             called (This has been deprecated; developers should let Android call onDestroy() and
-             then restore the app state in onCreate()
-         -->
-        <activity
-            android:name="NoteEditor"
+        <activity android:name="NoteEditor"
             android:theme="@android:style/Theme.Light"
             android:label="@string/title_note"
             android:screenOrientation="sensor"
-            android:configChanges="keyboardHidden|orientation" >
-            <!--
-                Allows viewing or editing data, including the application-created EDIT_NOTE
-                intent, for a single note of type vnd.google.note
-            -->
+            android:configChanges="keyboardHidden|orientation"
+        >
+            <!-- This filter says that we can view or edit the data of
+                 a single note -->
             <intent-filter android:label="@string/resolve_edit">
                 <action android:name="android.intent.action.VIEW" />
                 <action android:name="android.intent.action.EDIT" />
@@ -124,9 +64,10 @@
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
 
-            <!--
-                Allows inserting a note into a list of notes of type vnd.google.note
-             -->
+            <!-- This filter says that we can create a new note inside
+                 of a directory of notes.  The INSERT action creates an
+                 empty note; the PASTE action initializes a new note from
+                 the current contents of the clipboard. -->
             <intent-filter>
                 <action android:name="android.intent.action.INSERT" />
                 <action android:name="android.intent.action.PASTE" />
@@ -136,53 +77,42 @@
 
         </activity>
 
-        <!--
-            Defines the title editor Activity. This Activity uses a dialog view, which
-            looks like a regular dialog but is reachable by an Intent and uses
-            intent filters. The soft keyboard is made visible when input is expected.
-         -->
-        <activity
-            android:name="TitleEditor"
+        <activity android:name="TitleEditor"
             android:label="@string/title_edit_title"
             android:theme="@android:style/Theme.Dialog"
             android:windowSoftInputMode="stateVisible">
-            <!--
-                This intent-filter accepts the application-specific EDIT_TITLE intent. It
-                also accepts DEFAULT (required by non-MAIN activities). Because it is specified
-                with ALTERNATIVE and SELECTED_ALTERNATIVE, the activity will appear as an
-                alternative in a list of activities that work on the data type listed.
-                This activity can only work on a single notes object.
-             -->
+            <!-- This activity implements an alternative action that can be
+                 performed on notes: editing their title.  It can be used as
+                 a default operation if the user invokes this action, and is
+                 available as an alternative action for any note data. -->
             <intent-filter android:label="@string/resolve_title">
+                <!-- This is the action we perform.  It is a custom action we
+                     define for our application, not a generic VIEW or EDIT
+                     action since we are not a general note viewer/editor. -->
                 <action android:name="com.android.notepad.action.EDIT_TITLE" />
+                <!-- DEFAULT: execute if being directly invoked. -->
                 <category android:name="android.intent.category.DEFAULT" />
+                <!-- ALTERNATIVE: show as an alternative action when the user is
+                     working with this type of data. -->
                 <category android:name="android.intent.category.ALTERNATIVE" />
+                <!-- SELECTED_ALTERNATIVE: show as an alternative action the user
+                     can perform when selecting this type of data. -->
                 <category android:name="android.intent.category.SELECTED_ALTERNATIVE" />
+                <!-- This is the data type we operate on. -->
                 <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
             </intent-filter>
         </activity>
-        <!--
-            This activity handles live folder views of notes. The CREATE_LIVE_FOLDER filter
-            tells the Launcher that this activity can handle live folders.
-        -->
-        <activity
-            android:name="NotesLiveFolder"
-            android:label="@string/live_folder_name"
+
+        <activity android:name="NotesLiveFolder" android:label="@string/live_folder_name"
             android:icon="@drawable/live_folder_notes">
             <intent-filter>
                 <action android:name="android.intent.action.CREATE_LIVE_FOLDER" />
                 <category android:name="android.intent.category.DEFAULT" />
             </intent-filter>
         </activity>
-        <!--
-            This declares version information for the application:
-            targetSdkVersion: Indicates that the application was tested with API level 4.
-            Android will turn off compatibility features for APIs greater than 4, since the
-            application does not require them. Also, if the application were to be uploaded to
-            Android Market, then it would not be visible to devices running an API level below 4.
-            minSdkVersion: Indicates that Android will not install this application to a
-            device that is running an API level less than 4.
-        -->
-        <uses-sdk android:targetSdkVersion="3" android:minSdkVersion="3"/>
+
     </application>
+
+    <uses-sdk android:targetSdkVersion="4" android:minSdkVersion="3"/>
 </manifest>
+
diff --git a/samples/NotePad/_index.html b/samples/NotePad/_index.html
index d263fda..8f680ef 100644
--- a/samples/NotePad/_index.html
+++ b/samples/NotePad/_index.html
@@ -1,62 +1,20 @@
-<h2>NotePad Documentation</h2>
-<p>
-    NotePad is a simple application for entering and saving character-only notes.
-    It demonstrates the following Android concepts:
-</p>
-<ul>
-    <li>ListView objects with Cursor-based adapters.</li>
-    <li>Data storage and access with a ContentProvider.</li>
-    <li>Intent filters that handle multiple actions.</li>
-    <li>Activity objects that handle more than one Intent.</li>
-    <li>Sending an Intent by selecting an item from a ListView.</li>
-    <li>Sending data in an Intent.</li>
-    <li>Dynamic construction of menus.</li>
-    <li>Context menus.</li>
-    <li>Providing other applications as alternative actions for a data item.</li>
-    <li>Creating <a href="../../../reference/android/provider/LiveFolders.html">
-    Live Folders</a></li>
-    <li>Setting up an application that does not use "save" or "exit". The application
-    saves the user's work whenever focus moves to another task. It remains available until
-    the system destroys it.</li>
+<p>A simple note pad application.
+It demonstrates:</p>
+<ul> 
+<li>Using views</li>
+<li>Accessing a database</li>
+<li>Using an intent to open a new window</li>
+<li>Managing activity lifecycle</li>
+<li>Creating <a href="../../../reference/android/provider/LiveFolders.html">Live Folders</a></li>
+<li>And more...</li>
 </ul>
-<h4>Functions</h4>
-<p>
-    By default, NotePad displays a list of existing notes,
-    and provides a menu that allows you to insert a new note. If you click an existing note, you
-    can edit it, or select the menu to delete it or edit its title. If you context-click an
-    existing note, you can also delete it. If you navigate away from a new note once you've entered
-    text, NotePad automatically saves what you've entered.
-</p>
-<h4>Limitations</h4>
-<p>
-    NotePad has limited functionality. It does not provide search/replace. It does not support
-    HTML or any other type of markup. However, it does have copy/paste if it is running on a
-    version of the Android platform that supports that functionality.
-</p>
-<h4>Provider</h4>
-<p>
-    Other applications can use NotePad's content provider to store notes. The "contract" for
-    the NotePad provider is documented in the Appendix.
-</p>
-<h4>Alternative actions</h4>
-<p>
-    Other applications can also register themselves to handle NotePad notes. To do this, they must
-    provide the necessary specifications in their manifest file. The specifications are listed in
-    the Appendix.
-</p>
-<h4>Test package</h4>
-<p>
-    This sample also contains a test package that demonstrates how to test a ContentProvider and
-    an Activity. To learn more about this test package, please read
-    <a href="tests/index.html">NotePadTest Documentation</a>
-</p>
-<p class="note">
-    Please notice that this is not the same code that's used for the
-    <a href="../../../guide/tutorials/notepad/index.html">Notepad Tutorial</a>. This code has been
-    updated more recently, and the tutorial is a more simple implementation. If you're new to
-    Android development, you should start with the tutorial, then return to this code.
-</p>
-<h4>Appendix A: Provider contract</h4>
-<h4>Appendix B: Registering an application</h4>
+
+<p class="note">Please notice that this is not the same
+notepad code that's used for the <a href="../../../guide/tutorials/notepad/index.html">Notepad Tutorial</a>. 
+They are similar in nature, but there are several differences in implementation &mdash; the tutorial
+is slightly more simple. If you're new to 
+Android development, we suggest you start with the tutorial, then visit this
+code later to see more sample code.</p>
+
 <img alt="" src="../images/sample_notepad.png" />
 <img alt="" src="../images/sample_note.png" />
diff --git a/samples/NotePad/res/layout/note_editor.xml b/samples/NotePad/res/layout/note_editor.xml
index dae6d7f..d7da99e 100644
--- a/samples/NotePad/res/layout/note_editor.xml
+++ b/samples/NotePad/res/layout/note_editor.xml
@@ -4,9 +4,9 @@
      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.
@@ -14,15 +14,11 @@
      limitations under the License.
 -->
 
-<!--
-    android:layout_width and android:layout_height use "fill_parent" to be compatible with API
-    level 4. The setting was renamed "match_parent" in API level 8.
- -->
 <view xmlns:android="http://schemas.android.com/apk/res/android"
     class="com.example.android.notepad.NoteEditor$LinedEditText"
     android:id="@+id/note"
-    android:layout_width="fill_parent"
-    android:layout_height="fill_parent"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
     android:background="@android:color/transparent"
     android:padding="5dip"
     android:scrollbars="vertical"
diff --git a/samples/NotePad/res/layout/noteslist_item.xml b/samples/NotePad/res/layout/noteslist_item.xml
index ddb468d..e11c5ee 100644
--- a/samples/NotePad/res/layout/noteslist_item.xml
+++ b/samples/NotePad/res/layout/noteslist_item.xml
@@ -4,22 +4,19 @@
      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.
 -->
-<!--
-    android:layout_width and android:layout_height use "fill_parent" to be compatible with API
-    level 4. The setting was renamed "match_parent" in API level 8.
- -->
+
 <TextView xmlns:android="http://schemas.android.com/apk/res/android"
     android:id="@android:id/text1"
-    android:layout_width="fill_parent"
+    android:layout_width="match_parent"
     android:layout_height="?android:attr/listPreferredItemHeight"
     android:textAppearance="?android:attr/textAppearanceLarge"
     android:gravity="center_vertical"
diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
index d01974e..57b4646 100644
--- a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
@@ -16,10 +16,13 @@
 
 package com.example.android.notepad;
 
-import com.example.android.notepad.NotePad;
+import com.example.android.notepad.NotePad.Notes;
 
 import android.app.Activity;
+import android.content.ClipboardManager;
+import android.content.ClippedData;
 import android.content.ComponentName;
+import android.content.ContentResolver;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.Intent;
@@ -36,31 +39,28 @@
 import android.widget.EditText;
 
 /**
- * This Activity handles "editing" a note, where editing is responding to
- * {@link Intent#ACTION_VIEW} (request to view data), edit a note
- * {@link Intent#ACTION_EDIT}, or create a note {@link Intent#ACTION_INSERT}.
- *
- * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
- * This is not a good practice. It is only done here to make the code more readable. A real
- * application should use the {@link android.content.AsyncQueryHandler}
- * or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
+ * A generic activity for editing a note in a database.  This can be used
+ * either to simply view a note {@link Intent#ACTION_VIEW}, view and edit a note
+ * {@link Intent#ACTION_EDIT}, or create a new empty note
+ * {@link Intent#ACTION_INSERT}, or create a new note from the current contents
+ * of the clipboard {@link Intent#ACTION_PASTE}.
  */
 public class NoteEditor extends Activity {
-    // For logging and debugging purposes
     private static final String TAG = "Notes";
 
-    /*
-     * Creates a projection that returns the note ID and the note contents.
+    /**
+     * Standard projection for the interesting columns of a normal note.
      */
-    private static final String[] PROJECTION
-        = new String[] {
-            NotePad.Notes._ID,
-            NotePad.Notes.COLUMN_NAME_NOTE
+    private static final String[] PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.NOTE, // 1
+            Notes.TITLE, // 2
     };
-
     /** The index of the note column */
     private static final int COLUMN_INDEX_NOTE = 1;
-
+    /** The index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 2;
+    
     // This is our state data that is stored when freezing.
     private static final String ORIGINAL_CONTENT = "origContent";
 
@@ -72,111 +72,73 @@
     // The different distinct states the activity can be run in.
     private static final int STATE_EDIT = 0;
     private static final int STATE_INSERT = 1;
+    private static final int STATE_PASTE = 2;
 
-    // Global variables
     private int mState;
+    private boolean mNoteOnly = false;
     private Uri mUri;
     private Cursor mCursor;
     private EditText mText;
     private String mOriginalContent;
 
     /**
-     * Defines a custom EditText View that draws lines between each line of text that is displayed.
+     * A custom EditText that draws lines between each line of text that is displayed.
      */
     public static class LinedEditText extends EditText {
         private Rect mRect;
         private Paint mPaint;
 
-        // This constructor is used by LayoutInflater
+        // we need this constructor for LayoutInflater
         public LinedEditText(Context context, AttributeSet attrs) {
             super(context, attrs);
-
-            // Creates a Rect and a Paint object, and sets the style and color of the Paint object.
+            
             mRect = new Rect();
             mPaint = new Paint();
             mPaint.setStyle(Paint.Style.STROKE);
             mPaint.setColor(0x800000FF);
         }
-
-        /**
-         * This is called to draw the LinedEditText object
-         * @param canvas The canvas on which the background is drawn.
-         */
+        
         @Override
         protected void onDraw(Canvas canvas) {
-
-            // Gets the number of lines of text in the View.
             int count = getLineCount();
-
-            // Gets the global Rect and Paint objects
             Rect r = mRect;
             Paint paint = mPaint;
 
-            /*
-             * Draws one line in the rectangle for every line of text in the EditText
-             */
             for (int i = 0; i < count; i++) {
-
-                // Gets the baseline coordinates for the current line of text
                 int baseline = getLineBounds(i, r);
 
-                // Draws a line in the background from the left of the rectangle to the right,
-                // at a vertical position one dip below the baseline, using the "paint" object
-                // for details.
                 canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
             }
 
-            // Finishes up by calling the parent method
             super.onDraw(canvas);
         }
     }
 
-    /**
-     * This method is called by Android when the Activity is first started. From the incoming
-     * Intent, it determines what kind of editing is desired, and then does it.
-     */
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        /*
-         * Creates an Intent to use when the Activity object's result is sent back to the
-         * caller.
-         */
         final Intent intent = getIntent();
 
-        /*
-         *  Sets up for the edit, based on the action specified for the incoming Intent.
-         */
+        // Do some setup based on the action being performed.
 
-        // Gets the action that triggered the intent filter for this Activity
         final String action = intent.getAction();
-
-        // For an edit action:
         if (Intent.ACTION_EDIT.equals(action)) {
-
-            // Sets the Activity state to EDIT, and gets the URI for the data to be edited.
+            // Requested to edit: set that state, and the data being edited.
             mState = STATE_EDIT;
             mUri = intent.getData();
-
-        // For an insert action:
-        } else if (Intent.ACTION_INSERT.equals(action)) {
-
-            // Sets the Activity state to INSERT, gets the general note URI, and inserts an
-            // empty record in the provider
+        } else if (Intent.ACTION_INSERT.equals(action)
+                || Intent.ACTION_PASTE.equals(action)) {
+            // Requested to insert: set that state, and create a new entry
+            // in the container.
             mState = STATE_INSERT;
             mUri = getContentResolver().insert(intent.getData(), null);
 
-            /*
-             * If the attempt to insert the new note fails, shuts down this Activity. The
-             * originating Activity receives back RESULT_CANCELED if it requested a result.
-             * Logs that the insert failed.
-             */
+            // If we were unable to create a new note, then just finish
+            // this activity.  A RESULT_CANCELED will be sent back to the
+            // original activity if they requested a result.
             if (mUri == null) {
-                // Writes the log identifier, a message, and the URI that failed.
                 Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
-
-                // Closes the activity.
                 finish();
                 return;
             }
@@ -185,425 +147,266 @@
             // set the result to be returned.
             setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
 
-        // If the action was other than EDIT or INSERT:
+            // If pasting, initialize data from clipboard.
+            if (Intent.ACTION_PASTE.equals(action)) {
+                performPaste();
+                // Switch to paste mode; can no longer modify title.
+                mState = STATE_PASTE;
+            }
+
         } else {
-            // Logs an error that the action was not understood, finishes the Activity, and
-            // returns RESULT_CANCELED to an originating Activity.
+            // Whoops, unknown action!  Bail.
             Log.e(TAG, "Unknown action, exiting");
             finish();
             return;
         }
 
-        // Sets the layout for this Activity. See res/layout/note_editor.xml
+        // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
         setContentView(R.layout.note_editor);
-
-        // Gets a handle to the EditText in the the layout.
+        
+        // The text view for our note, identified by its ID in the XML file.
         mText = (EditText) findViewById(R.id.note);
 
-        /*
-         * Using the URI passed in with the triggering Intent, gets the note or notes in
-         * the provider.
-         * Note: This is being done on the UI thread. It will block the thread until the query
-         * completes. In a sample app, going against a simple provider based on a local database,
-         * the block will be momentary, but in a real app you should use
-         * android.content.AsyncQueryHandler or android.os.AsyncTask.
-         */
-        mCursor = managedQuery(
-            mUri,         // The URI that gets multiple notes from the provider.
-            PROJECTION,   // A projection that returns the note ID and note content for each note.
-            null,         // No "where" clause selection criteria.
-            null,         // No "where" clause selection values.
-            null          // Use the default sort order (modification date, descending)
-        );
+        // Get the note!
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
 
-        /*
-         * If this Activity had stopped previously, its state was written the ORIGINAL_CONTENT
-         * location in the saved Instance state. This gets the state.
-         */
+        // If an instance of this activity had previously stopped, we can
+        // get the original text it started with.
         if (savedInstanceState != null) {
             mOriginalContent = savedInstanceState.getString(ORIGINAL_CONTENT);
         }
     }
 
-    /**
-     * This method is called when the Activity is about to come to the foreground. This happens
-     * when the Activity comes to the top of the task stack, OR when it is first starting.
-     *
-     * Moves to the first note in the list, sets an appropriate title for the action chosen by
-     * the user, puts the note contents into the TextView, and saves the original text as a
-     * backup.
-     */
     @Override
     protected void onResume() {
         super.onResume();
 
-        /*
-         * mCursor is initialized, since onCreate() always precedes onResume for any running
-         * process. This tests that it's not null, since it should always contain data.
-         */
+        // If we didn't have any trouble retrieving the data, it is now
+        // time to get at the stuff.
         if (mCursor != null) {
-
-            /* Moves to the first record. Always call moveToFirst() before accessing data in
-             * a Cursor for the first time. The semantics of using a Cursor are that when it is
-             * created, its internal index is pointing to a "place" immediately before the first
-             * record.
-             */
+            // Make sure we are at the one and only row in the cursor.
             mCursor.moveToFirst();
 
-            // Modifies the window title for the Activity according to the current Activity state.
+            // Modify our overall title depending on the mode we are running in.
             if (mState == STATE_EDIT) {
-
-                // Sets the title to "edit"
                 setTitle(getText(R.string.title_edit));
-            } else if (mState == STATE_INSERT) {
-
-                // Sets the title to "create"
+            } else if (mState == STATE_INSERT || mState == STATE_PASTE) {
                 setTitle(getText(R.string.title_create));
             }
 
-            /*
-             * onResume() may have been called after the Activity lost focus (was paused).
-             * The user was either editing or creating a note when the Activity paused.
-             * The Activity should re-display the text that had been retrieved previously, but
-             * it should not move the cursor. This helps the user to continue editing or entering.
-             */
-
-            // Gets the note text from the Cursor and puts it in the TextView, but doesn't change
-            // the text cursor's position.
+            // This is a little tricky: we may be resumed after previously being
+            // paused/stopped.  We want to put the new text in the text view,
+            // but leave the user where they were (retain the cursor position
+            // etc).  This version of setText does that for us.
             String note = mCursor.getString(COLUMN_INDEX_NOTE);
             mText.setTextKeepState(note);
-
-            // Stores the original note text, to allow the user to revert changes.
+            
+            // If we hadn't previously retrieved the original text, do so
+            // now.  This allows the user to revert their changes.
             if (mOriginalContent == null) {
                 mOriginalContent = note;
             }
 
-        /*
-         * Something is wrong. The Cursor should always contain data. Report an error in the
-         * note.
-         */
         } else {
             setTitle(getText(R.string.error_title));
             mText.setText(getText(R.string.error_message));
         }
     }
 
-    /**
-     * This method is called when an Activity loses focus during its normal operation, and is then
-     * later on killed. The Activity has a chance to save its state so that the system can restore
-     * it.
-     *
-     * Notice that this method isn't a normal part of the Activity lifecycle. It won't be called
-     * if the user simply navigates away from the Activity.
-     */
     @Override
     protected void onSaveInstanceState(Bundle outState) {
-        // Saves away the original text, so we still have it if the activity
+        // Save away the original text, so we still have it if the activity
         // needs to be killed while paused.
         outState.putString(ORIGINAL_CONTENT, mOriginalContent);
     }
 
-    /**
-     * This method is called when the Activity loses focus.
-     *
-     * For Activity objects that edit information, onPause() may be the one place where changes are
-     * saved. The Android application model is predicated on the idea that "save" and "exit" aren't
-     * required actions. When users navigate away from an Activity, they shouldn't have to go back
-     * to it to complete their work. The act of going away should save everything and leave the
-     * Activity in a state where Android can destroy it if necessary.
-     *
-     * If the user hasn't done anything, then this deletes or clears out the note, otherwise it
-     * writes the user's work to the provider.
-     */
     @Override
     protected void onPause() {
         super.onPause();
 
-        /*
-         * Tests to see that the query operation didn't fail (see onCreate()). The Cursor object
-         * will exist, even if no records were returned, unless the query failed because of some
-         * exception or error.
-         *
-         */
+        // The user is going somewhere else, so make sure their current
+        // changes are safely saved away in the provider.  We don't need
+        // to do this if only editing.
         if (mCursor != null) {
-
-            // Get the current note text.
             String text = mText.getText().toString();
-            int note_length = text.length();
+            int length = text.length();
 
-            /*
-             * If the Activity is in the midst of finishing and there is no text in the current
-             * note, returns a result of CANCELED to the caller, and deletes the note. This is done
-             * even if the note was being edited, the assumption being that the user wanted to
-             * "clear out" (delete) the note.
-             */
-            if (isFinishing() && (note_length == 0)) {
+            // If this activity is finished, and there is no text, then we
+            // do something a little special: simply delete the note entry.
+            // Note that we do this both for editing and inserting...  it
+            // would be reasonable to only do it when inserting.
+            if (isFinishing() && (length == 0) && !mNoteOnly) {
                 setResult(RESULT_CANCELED);
                 deleteNote();
 
-            /*
-             * Writes the edits to the provider. The note has been edited if an existing note was
-             * retrieved into the editor *or* if a new note was inserted. In the latter case,
-             * onCreate() inserted a new empty note into the provider, and it is this new note
-             * that is being edited.
-             */
+            // Get out updates into the provider.
             } else {
-                // Creates a map to contain the new values for the columns
-                ContentValues values = new ContentValues();
-
-                // In the values map, sets the modification date column to the current time.
-                values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, System.currentTimeMillis());
-
-                // Creates a title for a newly-inserted note.
-                if (mState == STATE_INSERT) {
-
-                    // Gets the first 30 characters of the note, or the entire note if it's
-                    // less than 30 characters long.
-                    String title = text.substring(0, Math.min(30, note_length));
-
-                    // If the note's entire length is greater than 30, then the title is 30
-                    // characters long. Finds the last occurrence of blank in the title, and
-                    // removes all characters to the right of it from the title string.
-                    if (note_length > 30) {
-                        int lastSpace = title.lastIndexOf(' ');
-                        if (lastSpace > 0) {
-                            title = title.substring(0, lastSpace);
-                        }
-                    }
-                    // In the values map, set the title column to the new title.
-                    values.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
-                }
-
-                // In the values map, sets the note text column to the text in the View.
-                values.put(NotePad.Notes.COLUMN_NAME_NOTE, text);
-
-                /*
-                 * Updates the provider with the new values in the map. The ListView is updated
-                 * automatically. The provider sets this up by setting the notification URI for
-                 * query Cursor objects to the incoming URI. The content resolver is thus
-                 * automatically notified when the Cursor for the URI changes, and the UI is
-                 * updated.
-                 * Note: This is being done on the UI thread. It will block the thread until the
-                 * update completes. In a sample app, going against a simple provider based on a
-                 * local database, the block will be momentary, but in a real app you should use
-                 * android.content.AsyncQueryHandler or android.os.AsyncTask.
-                 */
-                getContentResolver().update(
-                    mUri,    // The URI for the record to update.
-                    values,  // The map of column names and new values to apply to them.
-                    null,    // No selection criteria are used, so no where columns are necessary.
-                    null     // No where columns are used, so no where arguments are necessary.
-                );
+                updateNote(text, null, !mNoteOnly);
             }
         }
     }
 
-    /**
-     * This method is called when the user clicks the device's Menu button the first time for
-     * this Activity. Android passes in a Menu object that is populated with items.
-     *
-     * Builds the menus for editing and inserting, and adds in alternative actions that
-     * registered themselves to handle the MIME types for this application.
-     *
-     * @param menu A Menu object to which items should be added.
-     * @return True to display the menu.
-     */
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
 
-        // Builds the menus that are shown when editing. These are 'revert' to undo changes, and
-        // 'delete' to delete the note.
+        // Build the menus that are shown when editing.
         if (mState == STATE_EDIT) {
-
-            // Adds the 'revert' menu item, and sets its shortcut to numeric 0, letter 'r' and its
-            // icon to the Android standard revert icon.
             menu.add(0, REVERT_ID, 0, R.string.menu_revert)
-                .setShortcut('0', 'r')
-                .setIcon(android.R.drawable.ic_menu_revert);
+                    .setShortcut('0', 'r')
+                    .setIcon(android.R.drawable.ic_menu_revert);
+            if (!mNoteOnly) {
+                menu.add(0, DELETE_ID, 0, R.string.menu_delete)
+                        .setShortcut('1', 'd')
+                        .setIcon(android.R.drawable.ic_menu_delete);
+            }
 
-            // Adds the 'delete' menu item, and sets its shortcut to numeric 1, letter 'd' and its
-            // icon to the Android standard delete icon
-            menu.add(0, DELETE_ID, 0, R.string.menu_delete)
-                .setShortcut('1', 'd')
-                .setIcon(android.R.drawable.ic_menu_delete);
-
-        // Builds the menus that are shown when inserting. The only option is 'Discard' to throw
-        // away the new note.
+        // Build the menus that are shown when inserting.
         } else {
-
-            // Adds the 'discard' menu item, using the 'delete' shortcuts and icon.
             menu.add(0, DISCARD_ID, 0, R.string.menu_discard)
                     .setShortcut('0', 'd')
                     .setIcon(android.R.drawable.ic_menu_delete);
         }
 
-        /*
-         * Appends menu items for any Activity declarations that implement an alternative action
-         * for this Activity's MIME type, one menu item for each Activity.
-         */
-        // Makes a new Intent with the URI data passed to this Activity
-        Intent intent = new Intent(null, getIntent().getData());
+        // If we are working on a full note, then append to the
+        // menu items for any other activities that can do stuff with it
+        // as well.  This does a query on the system for any activities that
+        // implement the ALTERNATIVE_ACTION for our data, adding a menu item
+        // for each one that is found.
+        if (!mNoteOnly) {
+            Intent intent = new Intent(null, getIntent().getData());
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
+                    new ComponentName(this, NoteEditor.class), null, intent, 0, null);
+        }
 
-        // Adds the ALTERNATIVE category to the Intent.
-        intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
-
-        /*
-         * Constructs a new ComponentName object that represents the current Activity.
-         */
-        ComponentName component = new ComponentName(
-            this,
-            NoteEditor.class);
-
-        /*
-         * In the ALTERNATIVE menu group, adds an option for each Activity that is registered to
-         * handle this Activity's MIME type. The Intent describes what type of items should be
-         * added to the menu; in this case, Activity declarations with category ALTERNATIVE.
-         */
-        menu.addIntentOptions(
-            Menu.CATEGORY_ALTERNATIVE,  // The menu group to add the items to.
-            Menu.NONE,                  // No unique ID is needed.
-            Menu.NONE,                  // No ordering is needed.
-            component,                  // The current Activity object's component name
-            null,                       // No specific items need to be placed first.
-            intent,                     // The intent containing the type of items to add.
-            Menu.NONE,                  // No flags are necessary.
-            null                        // No need to generate an array of menu items.
-        );
-
-        // The method returns TRUE, so that further menu processing is not done.
         return true;
     }
 
-    /**
-     * This method is called when a menu item is selected. Android passes in the selected item.
-     * The switch statement in this method calls the appropriate method to perform the action the
-     * user chose.
-     *
-     * @param item The selected MenuItem
-     * @return True to indicate that the item was processed, and no further work is necessary. False
-     * to proceed to further processing as indicated in the MenuItem object.
-     */
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-        // Chooses the action to perform
+        // Handle all of the possible menu actions.
         switch (item.getItemId()) {
-
-        // Deletes the note and close the Activity.
         case DELETE_ID:
             deleteNote();
             finish();
             break;
-
-        // Discards the new note.
         case DISCARD_ID:
             cancelNote();
             break;
-
-        // Discards any changes to an edited note.
         case REVERT_ID:
             cancelNote();
             break;
         }
-
-        // Continues with processing the menu item. In effect, if the item was an alternative
-        // action, this invokes the Activity for that action.
         return super.onOptionsItemSelected(item);
     }
 
+//BEGIN_INCLUDE(paste)
     /**
-     * Takes care of canceling work on a note.  Deletes the note if we
-     * had created it, otherwise reverts to the original text.
+     * Replace the note's data with the current contents of the clipboard.
      */
-    private final void cancelNote() {
+    private final void performPaste() {
+        ClipboardManager clipboard = (ClipboardManager)
+                getSystemService(Context.CLIPBOARD_SERVICE);
+        ContentResolver cr = getContentResolver();
 
-        /*
-         * Tests to see that the original query operation didn't fail (see onCreate()). The Cursor
-         * object will exist, even if no records were returned, unless the query failed because of
-         * some exception or error.
-         */
-        if (mCursor != null) {
+        ClippedData clip = clipboard.getPrimaryClip();
+        if (clip != null) {
+            String text=null, title=null;
 
-            /*
-             * If the user is editing a note, and asked to discard or revert, this puts the
-             * previous note contents back into the note.
-             */
-            if (mState == STATE_EDIT) {
+            ClippedData.Item item = clip.getItem(0);
+            Uri uri = item.getUri();
+            if (uri != null && NotePad.Notes.CONTENT_ITEM_TYPE.equals(cr.getType(uri))) {
+                // The clipboard holds a reference to a note.  Copy it.
+                Cursor orig = cr.query(uri, PROJECTION, null, null, null);
+                if (orig != null) {
+                    if (orig.moveToFirst()) {
+                        text = orig.getString(COLUMN_INDEX_NOTE);
+                        title = orig.getString(COLUMN_INDEX_TITLE);
+                    }
+                    orig.close();
+                }
+            }
 
-                // Closes the previous cursor prior to updating the provider
-                mCursor.close();
-                mCursor = null;
+            // If we weren't able to load the clipped data as a note, then
+            // convert whatever it is to text.
+            if (text == null) {
+                text = item.coerceToText(this).toString();
+            }
 
-                // Creates a new values map
-                ContentValues values = new ContentValues();
+            updateNote(text, title, true);
+        }
+    }
+//END_INCLUDE(paste)
 
-                // Puts the original notes content into the values map. The variable was set in
-                // onResume().
-                values.put(NotePad.Notes.COLUMN_NAME_NOTE, mOriginalContent);
+    /**
+     * Replace the current note contents with the given data.
+     */
+    private final void updateNote(String text, String title, boolean updateTitle) {
+        ContentValues values = new ContentValues();
 
-                /*
-                 * Update the provider with the reverted note content.
-                 *
-                 * Note: This is being done on the UI thread. It will block the thread until the
-                 * update completes. In a sample app, going against a simple provider based on a
-                 * local database, the block will be momentary, but in a real app you should use
-                 * android.content.AsyncQueryHandler or android.os.AsyncTask.
-                 */
-                getContentResolver().update(
-                    mUri,    // The URI of the note or notes.
-                    values,  // The reverted values to put into the provider.
-                    null,    // No selection criteria, so no where columns are needed.
-                    null     // No where columns are used, so no where values are needed.
-                );
+        // This stuff is only done when working with a full-fledged note.
+        if (updateTitle) {
+            // Bump the modification time to now.
+            values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
 
-            /*
-             * If the user was inserting a note and decides to discard it, this deletes the note.
-             */
-            } else if (mState == STATE_INSERT) {
-                // Deletes the note.
-                deleteNote();
+            // If we are creating a new note, then we want to also create
+            // an initial title for it.
+            if (mState == STATE_INSERT) {
+                if (title == null) {
+                    int length = text.length();
+                    title = text.substring(0, Math.min(30, length));
+                    if (length > 30) {
+                        int lastSpace = title.lastIndexOf(' ');
+                        if (lastSpace > 0) {
+                            title = title.substring(0, lastSpace);
+                        }
+                    }
+                }
+                values.put(Notes.TITLE, title);
             }
         }
 
-        // Returns a result of CANCELED to the calling Activity.
-        setResult(RESULT_CANCELED);
+        // Write our text back into the provider.
+        values.put(Notes.NOTE, text);
 
-        // Finishes the Activity. Once the user deletes or discards, nothing more can be done, so
-        // return to the calling Activity, either NotesList or some other Activity.
+        // Commit all of our changes to persistent storage. When the update completes
+        // the content provider will notify the cursor of the change, which will
+        // cause the UI to be updated.
+        getContentResolver().update(mUri, values, null, null);
+
+    }
+
+    /**
+     * Take care of canceling work on a note.  Deletes the note if we
+     * had created it, otherwise reverts to the original text.
+     */
+    private final void cancelNote() {
+        if (mCursor != null) {
+            if (mState == STATE_EDIT) {
+                // Put the original note text back into the database
+                mCursor.close();
+                mCursor = null;
+                ContentValues values = new ContentValues();
+                values.put(Notes.NOTE, mOriginalContent);
+                getContentResolver().update(mUri, values, null, null);
+            } else if (mState == STATE_INSERT) {
+                // We inserted an empty note, make sure to delete it
+                deleteNote();
+            }
+        }
+        setResult(RESULT_CANCELED);
         finish();
     }
 
     /**
-     * This method deletes a note from the provider.
+     * Take care of deleting a note.  Simply deletes the entry.
      */
     private final void deleteNote() {
-        /*
-         * Tests to see that the original query operation didn't fail (see onCreate()). The Cursor
-         * object will exist, even if no records were returned, unless the query failed because of
-         * some exception or error.
-         */
         if (mCursor != null) {
-
-            // Gets rid of all the Cursor's resources, and deactivates it.
             mCursor.close();
             mCursor = null;
-
-            /*
-             * Deletes the note based on the ID in the URI.
-             *
-             * Note: This is being done on the UI thread. It will block the thread until the
-             * delete completes. In a sample app, going against a simple provider based on a
-             * local database, the block will be momentary, but in a real app you should use
-             * android.content.AsyncQueryHandler android.os.AsyncTask.
-             */
-
-            getContentResolver().delete(
-                mUri,  // The URI of the note to delete.
-                null,  // No selection criteria are specified, so no where columns are needed.
-                null   // No where columns are specified, so no where values are needed.
-            );
-
-            // Throws away any text currently showing in the View.
+            getContentResolver().delete(mUri, null, null);
             mText.setText("");
         }
     }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePad.java b/samples/NotePad/src/com/example/android/notepad/NotePad.java
index 624be90..25be23e 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotePad.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotePad.java
@@ -20,92 +20,25 @@
 import android.provider.BaseColumns;
 
 /**
- * Defines a contract between the Note Pad content provider and its clients. A contract defines the
- * information that a client needs to access the provider as one or more data tables. A contract
- * is a public, non-extendable (final) class that contains constants defining column names and
- * URIs. A well-written client depends only on the constants in the contract.
+ * Convenience definitions for NotePadProvider
  */
 public final class NotePad {
     public static final String AUTHORITY = "com.google.provider.NotePad";
 
     // This class cannot be instantiated
-    private NotePad() {
-    }
-
+    private NotePad() {}
+    
     /**
-     * Notes table contract
+     * Notes table
      */
     public static final class Notes implements BaseColumns {
-
         // This class cannot be instantiated
         private Notes() {}
 
         /**
-         * The table name offered by this provider
-         */
-        public static final String TABLE_NAME = "notes";
-
-        /*
-         * URI definitions
-         */
-
-        /**
-         * The scheme part for this provider's URI
-         */
-        private static final String SCHEME = "content://";
-
-        /**
-         * Path parts for the URIs
-         */
-
-        /**
-         * Path part for the Notes URI
-         */
-        private static final String PATH_NOTES = "/notes";
-
-        /**
-         * Path part for the Note ID URI
-         */
-        private static final String PATH_NOTE_ID = "/notes/";
-
-        /**
-         * 0-relative position of a note ID segment in the path part of a note ID URI
-         */
-        public static final int NOTE_ID_PATH_POSITION = 1;
-
-        /**
-         * Path part for the Live Folder URI
-         */
-        private static final String PATH_LIVE_FOLDER = "/live_folders/notes";
-
-        /**
          * The content:// style URL for this table
          */
-        public static final Uri CONTENT_URI =  Uri.parse(SCHEME + AUTHORITY + PATH_NOTES);
-
-        /**
-         * The content URI base for a single note. Callers must
-         * append a numeric note id to this Uri to retrieve a note
-         */
-        public static final Uri CONTENT_ID_URI_BASE
-            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID);
-
-        /**
-         * The content URI match pattern for a single note, specified by its ID. Use this to match
-         * incoming URIs or to construct an Intent.
-         */
-        public static final Uri CONTENT_ID_URI_PATTERN
-            = Uri.parse(SCHEME + AUTHORITY + PATH_NOTE_ID + "/#");
-
-        /**
-         * The content Uri pattern for a notes listing for live folders
-         */
-        public static final Uri LIVE_FOLDER_URI
-            = Uri.parse(SCHEME + AUTHORITY + PATH_LIVE_FOLDER);
-
-        /*
-         * MIME type definitions
-         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
 
         /**
          * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
@@ -113,8 +46,7 @@
         public static final String CONTENT_TYPE = "vnd.android.cursor.dir/vnd.google.note";
 
         /**
-         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single
-         * note.
+         * The MIME type of a {@link #CONTENT_URI} sub-directory of a single note.
          */
         public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
 
@@ -123,32 +55,28 @@
          */
         public static final String DEFAULT_SORT_ORDER = "modified DESC";
 
-        /*
-         * Column definitions
-         */
-
         /**
-         * Column name for the title of the note
+         * The title of the note
          * <P>Type: TEXT</P>
          */
-        public static final String COLUMN_NAME_TITLE = "title";
+        public static final String TITLE = "title";
 
         /**
-         * Column name of the note content
+         * The note itself
          * <P>Type: TEXT</P>
          */
-        public static final String COLUMN_NAME_NOTE = "note";
+        public static final String NOTE = "note";
 
         /**
-         * Column name for the creation timestamp
+         * The timestamp for when the note was created
          * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
          */
-        public static final String COLUMN_NAME_CREATE_DATE = "created";
+        public static final String CREATED_DATE = "created";
 
         /**
-         * Column name for the modification timestamp
+         * The timestamp for when the note was last modified
          * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
          */
-        public static final String COLUMN_NAME_MODIFICATION_DATE = "modified";
+        public static final String MODIFIED_DATE = "modified";
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
index c091d87..d79be24 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
@@ -16,11 +16,15 @@
 
 package com.example.android.notepad;
 
+import com.example.android.notepad.NotePad.Notes;
+
 import android.content.ContentProvider;
 import android.content.ContentUris;
 import android.content.ContentValues;
 import android.content.Context;
 import android.content.UriMatcher;
+import android.content.ContentProvider.PipeDataWriter;
+import android.content.res.AssetFileDescriptor;
 import android.content.res.Resources;
 import android.database.Cursor;
 import android.database.SQLException;
@@ -28,582 +32,340 @@
 import android.database.sqlite.SQLiteOpenHelper;
 import android.database.sqlite.SQLiteQueryBuilder;
 import android.net.Uri;
+import android.os.Bundle;
+import android.os.ParcelFileDescriptor;
 import android.provider.LiveFolders;
 import android.text.TextUtils;
 import android.util.Log;
 
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
 import java.util.HashMap;
 
 /**
- * This is a content provider for a table of notes. Each note has a title, the note
- * itself, a creation date and a modified data. The underlying data source is an SQLite
- * database.
- *
- * Notes:
- * SQLite database method signatures usually include a "where" argument and "whereArgs" argument.
- * "where" can either specify a full "where" clause in the format used by SQL "WHERE", or a
- * "where" clause in which the column names are followed by " = ?", or a combination of the two.
- * If the " = ?" form is present, then whereArgs must be non-null. It is a String array that
- * contains one element for each "?" present. In order, the "?" symbols are replace by elements
- * in whereArgs. This feature helps create selection criteria without needing to repeatedly
- * create a where clause from concatenations. In the comments, "where" is always annotated as
- * the where clause columns, and "whereArgs" as the where clause values, although "where" can
- * contain values and "whereArgs" can be null.
- *
+ * Provides access to a database of notes. Each note has a title, the note
+ * itself, a creation date and a modified data.
  */
-public class NotePadProvider extends ContentProvider {
+public class NotePadProvider extends ContentProvider implements PipeDataWriter<Cursor> {
 
-    // Used for debugging and logging
     private static final String TAG = "NotePadProvider";
 
-    /**
-     * The database that the provider uses as its underlying data store
-     */
     private static final String DATABASE_NAME = "note_pad.db";
-
-    /**
-     * The database version
-     */
     private static final int DATABASE_VERSION = 2;
+    private static final String NOTES_TABLE_NAME = "notes";
 
-    /**
-     * A projection map used to select columns from the database
-     */
     private static HashMap<String, String> sNotesProjectionMap;
-
-    /**
-     * A projection map used to select columns from the database
-     */
     private static HashMap<String, String> sLiveFolderProjectionMap;
 
-    /*
-     * Constants used by the Uri matcher to choose an action based on the pattern
-     * of the incoming URI
-     */
-    // The incoming URI matches the Notes URI pattern
     private static final int NOTES = 1;
-
-    // The incoming URI matches the Note ID URI pattern
     private static final int NOTE_ID = 2;
-
-    // The incoming URI matches the Live Folder URI pattern
     private static final int LIVE_FOLDER_NOTES = 3;
 
-    /**
-     * A UriMatcher instance
-     */
     private static final UriMatcher sUriMatcher;
 
-    // Handle to a new DatabaseHelper.
-    private DatabaseHelper mOpenHelper;
-
     /**
-     * A block that instantiates and sets static objects
+     * This class helps open, create, and upgrade the database file.
      */
-    static {
-
-        /*
-         * Creates and initializes the URI matcher
-         */
-        // Create a new instance
-        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
-
-        // Add a pattern that routes URIs terminated with "notes" to a NOTES operation
-        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
-
-        // Add a pattern that routes URIs terminated with "notes" plus an integer
-        // to a note ID operation
-        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
-
-        // Add a pattern that routes URIs terminated with live_folders/notes to a
-        // live folder operation
-        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
-
-        /*
-         * Creates and initializes a projection map that returns all columns
-         */
-
-        // Creates a new projection map instance. The map returns a column name
-        // given a string. The two are usually equal.
-        sNotesProjectionMap = new HashMap<String, String>();
-
-        // Maps the string "_ID" to the column name "_ID"
-        sNotesProjectionMap.put(NotePad.Notes._ID, NotePad.Notes._ID);
-
-        // Maps "title" to "title"
-        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_TITLE, NotePad.Notes.COLUMN_NAME_TITLE);
-
-        // Maps "note" to "note"
-        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_NOTE, NotePad.Notes.COLUMN_NAME_NOTE);
-
-        // Maps "created" to "created"
-        sNotesProjectionMap.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE,
-                NotePad.Notes.COLUMN_NAME_CREATE_DATE);
-
-        // Maps "modified" to "modified"
-        sNotesProjectionMap.put(
-                NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE,
-                NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE);
-
-        /*
-         * Creates an initializes a projection map for handling Live Folders
-         */
-
-        // Creates a new projection map instance
-        sLiveFolderProjectionMap = new HashMap<String, String>();
-
-        // Maps "_ID" to "_ID AS _ID" for a live folder
-        sLiveFolderProjectionMap.put(LiveFolders._ID, NotePad.Notes._ID + " AS " + LiveFolders._ID);
-
-        // Maps "NAME" to "title AS NAME"
-        sLiveFolderProjectionMap.put(LiveFolders.NAME, NotePad.Notes.COLUMN_NAME_TITLE + " AS " +
-            LiveFolders.NAME);
-    }
-
-
-
-    /**
-     *
-     * This class helps open, create, and upgrade the database file. Set to package visibility
-     * for testing purposes.
-     */
-    static class DatabaseHelper extends SQLiteOpenHelper {
+    private static class DatabaseHelper extends SQLiteOpenHelper {
 
         DatabaseHelper(Context context) {
-
-            // calls the super constructor, requesting the default cursor factory.
             super(context, DATABASE_NAME, null, DATABASE_VERSION);
         }
 
-        /**
-         *
-         * Creates the underlying database with table name and column names taken from the
-         * NotePad class.
-         */
         @Override
         public void onCreate(SQLiteDatabase db) {
-            db.execSQL("CREATE TABLE " + NotePad.Notes.TABLE_NAME + " ("
-                    + NotePad.Notes._ID + " INTEGER PRIMARY KEY,"
-                    + NotePad.Notes.COLUMN_NAME_TITLE + " TEXT,"
-                    + NotePad.Notes.COLUMN_NAME_NOTE + " TEXT,"
-                    + NotePad.Notes.COLUMN_NAME_CREATE_DATE + " INTEGER,"
-                    + NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE + " INTEGER"
+            db.execSQL("CREATE TABLE " + NOTES_TABLE_NAME + " ("
+                    + Notes._ID + " INTEGER PRIMARY KEY,"
+                    + Notes.TITLE + " TEXT,"
+                    + Notes.NOTE + " TEXT,"
+                    + Notes.CREATED_DATE + " INTEGER,"
+                    + Notes.MODIFIED_DATE + " INTEGER"
                     + ");");
         }
 
-        /**
-         *
-         * Demonstrates that the provider must consider what happens when the
-         * underlying datastore is changed. In this sample, the database is upgraded the database
-         * by destroying the existing data.
-         * A real application should upgrade the database in place.
-         */
         @Override
         public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
-
-            // Logs that the database is being upgraded
             Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
                     + newVersion + ", which will destroy all old data");
-
-            // Kills the table and existing data
             db.execSQL("DROP TABLE IF EXISTS notes");
-
-            // Recreates the database with a new version
             onCreate(db);
         }
     }
 
-    /**
-     *
-     * Initializes the provider by creating a new DatabaseHelper. onCreate() is called
-     * automatically when Android creates the provider in response to a resolver request from a
-     * client.
-     */
+    private DatabaseHelper mOpenHelper;
+
     @Override
     public boolean onCreate() {
-
-        // Creates a new helper object. Note that the database itself isn't opened until
-        // something tries to access it, and it's only created if it doesn't already exist.
         mOpenHelper = new DatabaseHelper(getContext());
-
-        // Assumes that any failures will be reported by a thrown exception.
         return true;
     }
 
-    /**
-     * This method is called when a client calls
-     * {@link android.content.ContentResolver#query(Uri, String[], String, String[], String)}.
-     * Queries the database and returns a cursor containing the results.
-     *
-     * @return A cursor containing the results of the query. The cursor exists but is empty if
-     * the query returns no results or an exception occurs.
-     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
-     */
     @Override
     public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
             String sortOrder) {
-
-        // Constructs a new query builder and sets its table name
         SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
-        qb.setTables(NotePad.Notes.TABLE_NAME);
+        qb.setTables(NOTES_TABLE_NAME);
 
-        /**
-         * Choose the projection and adjust the "where" clause based on URI pattern-matching.
-         */
         switch (sUriMatcher.match(uri)) {
-            // If the incoming URI is for notes, chooses the Notes projection
-            case NOTES:
-                qb.setProjectionMap(sNotesProjectionMap);
-                break;
+        case NOTES:
+            qb.setProjectionMap(sNotesProjectionMap);
+            break;
 
-            /* If the incoming URI is for a single note identified by its ID, chooses the
-             * note ID projection, and appends "_ID = <noteID>" to the where clause, so that
-             * it selects that single note
-             */
-            case NOTE_ID:
-                qb.setProjectionMap(sNotesProjectionMap);
-                qb.appendWhere(
-                    NotePad.Notes._ID +    // the name of the ID column
-                    "=" +
-                    // the position of the note ID itself in the incoming URI
-                    uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION));
-                break;
+        case NOTE_ID:
+            qb.setProjectionMap(sNotesProjectionMap);
+            qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
+            break;
 
-            case LIVE_FOLDER_NOTES:
-                // If the incoming URI is from a live folder, chooses the live folder projection.
-                qb.setProjectionMap(sLiveFolderProjectionMap);
-                break;
+        case LIVE_FOLDER_NOTES:
+            qb.setProjectionMap(sLiveFolderProjectionMap);
+            break;
 
-            default:
-                // If the URI doesn't match any of the known patterns, throw an exception.
-                throw new IllegalArgumentException("Unknown URI " + uri);
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
-
+        // If no sort order is specified use the default
         String orderBy;
-        // If no sort order is specified, uses the default
         if (TextUtils.isEmpty(sortOrder)) {
             orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
         } else {
-            // otherwise, uses the incoming sort order
             orderBy = sortOrder;
         }
 
-        // Opens the database object in "read" mode, since no writes need to be done.
+        // Get the database and run the query
         SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
 
-        /*
-         * Performs the query. If no problems occur trying to read the database, then a Cursor
-         * object is returned; otherwise, the cursor variable contains null. If no records were
-         * selected, then the Cursor object is empty, and Cursor.getCount() returns 0.
-         */
-        Cursor c = qb.query(
-            db,            // The database to query
-            projection,    // The columns to return from the query
-            selection,     // The columns for the where clause
-            selectionArgs, // The values for the where clause
-            null,          // don't group the rows
-            null,          // don't filter by row groups
-            orderBy        // The sort order
-        );
-
-        // Tells the Cursor what URI to watch, so it knows when its source data changes
+        // Tell the cursor what uri to watch, so it knows when its source data changes
         c.setNotificationUri(getContext().getContentResolver(), uri);
         return c;
     }
 
-    /**
-     * This is called when a client calls {@link android.content.ContentResolver#getType(Uri)}.
-     * Returns the MIME data type of the URI given as a parameter.
-     *
-     * @return The MIME type of the URI.
-     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
-     */
     @Override
     public String getType(Uri uri) {
-
-        /**
-         * Chooses the MIME type based on the incoming URI pattern
-         */
         switch (sUriMatcher.match(uri)) {
+        case NOTES:
+        case LIVE_FOLDER_NOTES:
+            return Notes.CONTENT_TYPE;
 
-            // If the pattern is for notes or live folders, returns the general content type.
-            case NOTES:
-            case LIVE_FOLDER_NOTES:
-                return NotePad.Notes.CONTENT_TYPE;
+        case NOTE_ID:
+            return Notes.CONTENT_ITEM_TYPE;
 
-            // If the pattern is for note IDs, returns the note ID content type.
-            case NOTE_ID:
-                return NotePad.Notes.CONTENT_ITEM_TYPE;
-
-            // If the pattern doesn't match any permitted patterns, throws an exception.
-            default:
-                throw new IllegalArgumentException("Unknown URI " + uri);
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
         }
     }
 
+//BEGIN_INCLUDE(stream)
     /**
-     * This is called when a client calls
-     * {@link android.content.ContentResolver#insert(Uri, ContentValues)}.
-     * Inserts a new row into the database. This method sets up default values for any
-     * columns that are not included in the incoming map.
-     * If rows were inserted, then listeners are notified of the change.
-     * @return The row ID of the inserted row.
-     * @throws SQLException if the insertion fails.
+     * Return the types of data streams we can return.  Currently we only
+     * support URIs to specific notes, and can convert such a note to a
+     * plain text stream.
      */
     @Override
-    public Uri insert(Uri uri, ContentValues initialValues) {
+    public String[] getStreamTypes(Uri uri, String mimeTypeFilter) {
+        switch (sUriMatcher.match(uri)) {
+            case NOTES:
+            case LIVE_FOLDER_NOTES:
+                return null;
 
-        // Validates the incoming URI. Only the full provider URI is allowed for inserts.
+            case NOTE_ID:
+                if (compareMimeTypes("text/plain", mimeTypeFilter)) {
+                    return new String[] { "text/plain" };
+                }
+                return null;
+
+            default:
+                throw new IllegalArgumentException("Unknown URI " + uri);
+            }
+    }
+
+    /**
+     * Standard projection for the interesting columns of a normal note.
+     */
+    private static final String[] READ_NOTE_PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.NOTE, // 1
+            NotePad.Notes.TITLE, // 2
+    };
+    private static final int READ_NOTE_NOTE_INDEX = 1;
+    private static final int READ_NOTE_TITLE_INDEX = 2;
+
+    /**
+     * Implement the other side of getStreamTypes: for each stream time we
+     * report to support, we need to actually be able to return a stream of
+     * data.  This function simply retrieves a cursor for the URI of interest,
+     * and uses ContentProvider's openPipeHelper() to start the work of
+     * convering the data off into another thread.
+     */
+    @Override
+    public AssetFileDescriptor openTypedAssetFile(Uri uri, String mimeTypeFilter, Bundle opts)
+            throws FileNotFoundException {
+        // Check if we support a stream MIME type for this URI.
+        String[] mimeTypes = getStreamTypes(uri, mimeTypeFilter);
+        if (mimeTypes != null) {
+            // Retrieve the note for this URI.
+            Cursor c = query(uri, READ_NOTE_PROJECTION, null, null, null);
+            if (c == null || !c.moveToFirst()) {
+                if (c != null) {
+                    c.close();
+                }
+                throw new FileNotFoundException("Unable to query " + uri);
+            }
+            // Start a thread to pipe the data back to the client.
+            return new AssetFileDescriptor(
+                    openPipeHelper(uri, mimeTypes[0], opts, c, this), 0,
+                    AssetFileDescriptor.UNKNOWN_LENGTH);
+        }
+        return super.openTypedAssetFile(uri, mimeTypeFilter, opts);
+    }
+
+    /**
+     * Implementation of {@link android.content.ContentProvider.PipeDataWriter}
+     * to perform the actual work of converting the data in one of cursors to a
+     * stream of data for the client to read.
+     */
+    @Override
+    public void writeDataToPipe(ParcelFileDescriptor output, Uri uri, String mimeType,
+            Bundle opts, Cursor c) {
+        // We currently only support conversion-to-text from a single note entry,
+        // so no need for cursor data type checking here.
+        FileOutputStream fout = new FileOutputStream(output.getFileDescriptor());
+        PrintWriter pw = null;
+        try {
+            pw = new PrintWriter(new OutputStreamWriter(fout, "UTF-8"));
+            pw.println(c.getString(READ_NOTE_TITLE_INDEX));
+            pw.println("");
+            pw.println(c.getString(READ_NOTE_NOTE_INDEX));
+        } catch (UnsupportedEncodingException e) {
+            Log.w(TAG, "Ooops", e);
+        } finally {
+            c.close();
+            if (pw != null) {
+                pw.flush();
+            }
+            try {
+                fout.close();
+            } catch (IOException e) {
+            }
+        }
+    }
+//END_INCLUDE(stream)
+
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+        // Validate the requested uri
         if (sUriMatcher.match(uri) != NOTES) {
             throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
-        // A map to hold the new record's values.
         ContentValues values;
-
-        // If the incoming values map is not null, uses it for the new values.
         if (initialValues != null) {
             values = new ContentValues(initialValues);
-
         } else {
-            // Otherwise, create a new value map
             values = new ContentValues();
         }
 
-        // Gets the current system time in milliseconds
         Long now = Long.valueOf(System.currentTimeMillis());
 
-        // If the values map doesn't contain the creation date, sets the value to the current time.
-        if (values.containsKey(NotePad.Notes.COLUMN_NAME_CREATE_DATE) == false) {
-            values.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, now);
+        // Make sure that the fields are all set
+        if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
+            values.put(NotePad.Notes.CREATED_DATE, now);
         }
 
-        // If the values map doesn't contain the modification date, sets the value to the current
-        // time.
-        if (values.containsKey(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE) == false) {
-            values.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, now);
+        if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
+            values.put(NotePad.Notes.MODIFIED_DATE, now);
         }
 
-        // If the values map doesn't contain a title, sets the value to the default title.
-        if (values.containsKey(NotePad.Notes.COLUMN_NAME_TITLE) == false) {
+        if (values.containsKey(NotePad.Notes.TITLE) == false) {
             Resources r = Resources.getSystem();
-            values.put(NotePad.Notes.COLUMN_NAME_TITLE, r.getString(android.R.string.untitled));
+            values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
         }
 
-        // If the values map doesn't contain note text, sets the value to an empty string.
-        if (values.containsKey(NotePad.Notes.COLUMN_NAME_NOTE) == false) {
-            values.put(NotePad.Notes.COLUMN_NAME_NOTE, "");
+        if (values.containsKey(NotePad.Notes.NOTE) == false) {
+            values.put(NotePad.Notes.NOTE, "");
         }
 
-        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
-        // Performs the insert and returns the ID of the new note.
-        long rowId = db.insert(
-            NotePad.Notes.TABLE_NAME,        // The table to insert into.
-            NotePad.Notes.COLUMN_NAME_NOTE,  // A hack, SQLite sets this column value to null
-                                             // if values is empty.
-            values                           // A map of column names, and the values to insert
-                                             // into the columns.
-        );
-
-        // If the insert succeeded, the row ID exists.
+        long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
         if (rowId > 0) {
-            // Creates a URI with the note ID pattern and the new row ID appended to it.
-            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, rowId);
-
-            // Notifies observers registered against this provider that the data changed.
+            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
             getContext().getContentResolver().notifyChange(noteUri, null);
             return noteUri;
         }
 
-        // If the insert didn't succeed, then the rowID is <= 0. Throws an exception.
         throw new SQLException("Failed to insert row into " + uri);
     }
 
-    /**
-     * This is called when a client calls
-     * {@link android.content.ContentResolver#delete(Uri, String, String[])}.
-     * Deletes records from the database. If the incoming URI matches the note ID URI pattern,
-     * this method deletes the one record specified by the ID in the URI. Otherwise, it deletes a
-     * a set of records. The record or records must also match the input selection criteria
-     * specified by where and whereArgs.
-     *
-     * If rows were deleted, then listeners are notified of the change.
-     * @return If a "where" clause is used, the number of rows affected is returned, otherwise
-     * 0 is returned. To delete all rows and get a row count, use "1" as the where clause.
-     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
-     */
     @Override
     public int delete(Uri uri, String where, String[] whereArgs) {
-
-        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
-
         int count;
-
-        // Does the delete based on the incoming URI pattern.
         switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
+            break;
 
-            // If the incoming pattern matches the general pattern for notes, does a delete
-            // based on the incoming "where" columns and arguments.
-            case NOTES:
-                count = db.delete(
-                    NotePad.Notes.TABLE_NAME,  // The database table name
-                    where,                     // The incoming where clause column names
-                    whereArgs                  // The incoming where clause values
-                );
-                break;
+        case NOTE_ID:
+            String noteId = uri.getPathSegments().get(1);
+            count = db.delete(NOTES_TABLE_NAME, Notes._ID + "=" + noteId
+                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
+            break;
 
-                // If the incoming URI matches a single note ID, does the delete based on the
-                // incoming data, but modifies the where clause to restrict it to the
-                // particular note ID.
-            case NOTE_ID:
-                // From the incoming URI, get the note ID
-                String noteId = uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION);
-
-                // If no where clause was passed in, uses the note ID column name
-                // for a column and the note ID for a value.
-                if (TextUtils.isEmpty(where)) {
-                    where = NotePad.Notes._ID + " = ?";
-                    whereArgs[0] = noteId;
-
-                } else {
-
-                    /*
-                     * If where clause columns were passed in, appends the note ID column name to
-                     * the list of columns using a replaceable parameter. This works even if the
-                     * other columns have actual values.
-                     */
-                    // Appends the note ID column name as an AND condition using a replaceable
-                    // parameter.
-                    where = where + " AND " + NotePad.Notes._ID + " = ?";
-
-                    // Appends the note ID value to the end of the where clause values.
-                    whereArgs[whereArgs.length] = noteId;
-                }
-
-                // Performs the delete.
-                count = db.delete(
-                    NotePad.Notes.TABLE_NAME,  // The database table name.
-                    where,                     // The incoming where clause column names.
-                    whereArgs                  // The incoming where clause values.
-                );
-                break;
-
-            // If the incoming pattern is invalid, throws an exception.
-            default:
-                throw new IllegalArgumentException("Unknown URI " + uri);
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
-        /*Gets a handle to the content resolver object for the current context, and notifies it
-         * that the incoming URI changed. The object passes this along to the resolver framework,
-         * and observers that have registered themselves for the provider are notified.
-         */
         getContext().getContentResolver().notifyChange(uri, null);
-
-        // Returns the number of rows deleted.
         return count;
     }
 
-    /**
-     * This is called when a client calls
-     * {@link android.content.ContentResolver#insert(Uri, ContentValues)}
-     * Updates records in the database. The column names specified by the keys in the values map
-     * are updated with new data specified by the values in the map. If the incoming URI matches the
-     * note ID URI pattern, then the method updates the one record specified by the ID in the URI;
-     * otherwise, it updates a set of records. The record or records must match the input
-     * selection criteria specified by where and whereArgs.
-     * If rows were updated, then listeners are notified of the change.
-     * @return The number of rows updated.
-     * @throws IllegalArgumentException if the incoming URI pattern is invalid.
-     */
     @Override
     public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
-
-        // Opens the database object in "write" mode.
         SQLiteDatabase db = mOpenHelper.getWritableDatabase();
         int count;
-
-        // Does the update based on the incoming URI pattern
         switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
+            break;
 
-            // If the incoming URI matches the general notes pattern, does the update based on
-            // the incoming data.
-            case NOTES:
+        case NOTE_ID:
+            String noteId = uri.getPathSegments().get(1);
+            count = db.update(NOTES_TABLE_NAME, values, Notes._ID + "=" + noteId
+                    + (!TextUtils.isEmpty(where) ? " AND (" + where + ')' : ""), whereArgs);
+            break;
 
-                // Does the update and returns the number of rows updated.
-                count = db.update(
-                    NotePad.Notes.TABLE_NAME, // The database table name.
-                    values,                   // A map of column names and new values to use.
-                    where,                    // The where clause column names.
-                    whereArgs                 // The where clause column values to select on.
-                );
-                break;
-
-            // If the incoming URI matches a single note ID, does the update based on the incoming
-            // data, but modifies the where clause to restrict it to the particular note ID.
-            case NOTE_ID:
-                // From the incoming URI, get the note ID
-                String noteId = uri.getPathSegments().get(NotePad.Notes.NOTE_ID_PATH_POSITION);
-
-                // If no where clause was passed in, uses the note ID column name
-                // for a column and the note ID for a value.
-                if (TextUtils.isEmpty(where)) {
-                    where = NotePad.Notes._ID + " = ?";
-                    whereArgs[0] = noteId;
-
-                    // If where clause columns were passed in, appends the note ID to the where
-                    // clause
-                } else {
-
-                    /*
-                     * Appends the note ID column name to the list of columns, with a replaceable
-                     * parameter. This will work even if the rest of the columns have been set with
-                     * actual values.
-                     */
-                    // Appends the note ID column name as an AND condition with a replaceable
-                    // parameter.
-                    where = where + " AND " + NotePad.Notes._ID + " = ?";
-
-                    // Appends the note ID value to the end of the where clause values.
-                    whereArgs[whereArgs.length] = noteId;
-                }
-
-                // Does the update.
-                // Does the update and returns the number of rows updated.
-                count = db.update(
-                    NotePad.Notes.TABLE_NAME, // The database table name.
-                    values,                   // A map of column names and new values to use.
-                    where,                    // The where clause column names.
-                    whereArgs                 // The where clause column values to select on.
-                );
-                break;
-            // If the incoming pattern is invalid, throws an exception.
-            default:
-                throw new IllegalArgumentException("Unknown URI " + uri);
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
         }
 
-        /*Gets a handle to the content resolver object for the current context, and notifies it
-         * that the incoming URI changed. The object passes this along to the resolver framework,
-         * and observers that have registered themselves for the provider are notified.
-         */
         getContext().getContentResolver().notifyChange(uri, null);
-
-        // Returns the number of rows updated.
         return count;
     }
 
-    /**
-     * A test package can call this to get a handle to the database underlying NotePadProvider,
-     * so it can insert test data into the database. The test case class is responsible for
-     * instantiating the provider in a test context; {@link android.test.ProviderTestCase2} does
-     * this during the call to setUp()
-     *
-     * @return a handle to the database helper object for the provider's data.
-     */
-    DatabaseHelper getOpenHelperForTest() {
-        return mOpenHelper;
+    static {
+        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "live_folders/notes", LIVE_FOLDER_NOTES);
+
+        sNotesProjectionMap = new HashMap<String, String>();
+        sNotesProjectionMap.put(Notes._ID, Notes._ID);
+        sNotesProjectionMap.put(Notes.TITLE, Notes.TITLE);
+        sNotesProjectionMap.put(Notes.NOTE, Notes.NOTE);
+        sNotesProjectionMap.put(Notes.CREATED_DATE, Notes.CREATED_DATE);
+        sNotesProjectionMap.put(Notes.MODIFIED_DATE, Notes.MODIFIED_DATE);
+
+        // Support for Live Folders.
+        sLiveFolderProjectionMap = new HashMap<String, String>();
+        sLiveFolderProjectionMap.put(LiveFolders._ID, Notes._ID + " AS " +
+                LiveFolders._ID);
+        sLiveFolderProjectionMap.put(LiveFolders.NAME, Notes.TITLE + " AS " +
+                LiveFolders.NAME);
+        // Add more columns here for more robust Live Folders.
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesList.java b/samples/NotePad/src/com/example/android/notepad/NotesList.java
index 63d480e..bbcb936 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotesList.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java
@@ -16,9 +16,14 @@
 
 package com.example.android.notepad;
 
+import com.example.android.notepad.NotePad.Notes;
+
 import android.app.ListActivity;
+import android.content.ClipboardManager;
+import android.content.ClippedData;
 import android.content.ComponentName;
 import android.content.ContentUris;
+import android.content.Context;
 import android.content.Intent;
 import android.database.Cursor;
 import android.net.Uri;
@@ -33,464 +38,217 @@
 import android.widget.ListView;
 import android.widget.SimpleCursorAdapter;
 
-import com.example.android.notepad.NotePad;
-
 /**
  * Displays a list of notes. Will display notes from the {@link Uri}
- * provided in the incoming Intent if there is one, otherwise it defaults to displaying the
- * contents of the {@link NotePadProvider}.
- *
- * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
- * This is not a good practice. It is only done here to make the code more readable. A real
- * application should use the {@link android.content.AsyncQueryHandler} or
- * {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
+ * provided in the intent if there is one, otherwise defaults to displaying the
+ * contents of the {@link NotePadProvider}
  */
 public class NotesList extends ListActivity {
-
-    // For logging and debugging
     private static final String TAG = "NotesList";
 
     // Menu item ids
     public static final int MENU_ITEM_DELETE = Menu.FIRST;
-    public static final int MENU_ITEM_INSERT = Menu.FIRST + 1;
-
+    public static final int MENU_ITEM_COPY = Menu.FIRST + 1;
+    public static final int MENU_ITEM_INSERT = Menu.FIRST + 2;
+    public static final int MENU_ITEM_PASTE = Menu.FIRST + 3;
 
     /**
-     * The columns needed by the cursor adapter
+     * The columns we are interested in from the database
      */
     private static final String[] PROJECTION = new String[] {
-            NotePad.Notes._ID, // 0
-            NotePad.Notes.COLUMN_NAME_TITLE, // 1
+            Notes._ID, // 0
+            Notes.TITLE, // 1
     };
 
-    /**
-     * onCreate is called when Android starts this Activity from scratch.
-     */
+    /** The index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 1;
+    
+    private MenuItem mPasteItem;
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        // The user does not need to hold down the key to use menu shortcuts.
         setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
 
-        /* If no data is given in the Intent that started this Activity, then this Activity
-         * was started when the intent filter matched a MAIN action. We should use the default
-         * provider URI.
-         */
-        // Gets the intent that started this Activity.
+        // If no data was given in the intent (because we were started
+        // as a MAIN activity), then use our default content provider.
         Intent intent = getIntent();
-
-        // If there is no data associated with the Intent, sets the data to the default URI, which
-        // accesses a list of notes.
         if (intent.getData() == null) {
-            intent.setData(NotePad.Notes.CONTENT_URI);
+            intent.setData(Notes.CONTENT_URI);
         }
 
-        /*
-         * Sets the callback for context menu activation for the ListView. The listener is set
-         * to be this Activity. The effect is that context menus are enabled for items in the
-         * ListView, and the context menu is handled by a method in NotesList.
-         */
-
+        // Inform the list we provide context menus for items
         getListView().setOnCreateContextMenuListener(this);
+        
+        // Perform a managed query. The Activity will handle closing and requerying the cursor
+        // when needed.
+        Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null,
+                Notes.DEFAULT_SORT_ORDER);
 
-        /* Performs a managed query. The Activity handles closing and requerying the cursor
-         * when needed.
-         *
-         * Please see the introductory note about performing provider operations on the UI thread.
-         */
-        Cursor cursor = managedQuery(
-            getIntent().getData(),            // Use the default content URI for the provider.
-            PROJECTION,                       // Return the note ID and title for each note.
-            null,                             // No where clause, return all records.
-            null,                             // No where clause, therefore no where column values.
-            NotePad.Notes.DEFAULT_SORT_ORDER  // Use the default sort order.
-        );
-
-        /*
-         * The following two arrays create a "map" between columns in the cursor and view IDs
-         * for items in the ListView. Each element in the dataColumns array represents
-         * a column name; each element in the viewID array represents the ID of a View.
-         * The SimpleCursorAdapter maps them in ascending order to determine where each column
-         * value will appear in the ListView.
-         */
-
-        // The names of the cursor columns to display in the view, initialized to the title column
-        String[] dataColumns = { NotePad.Notes.COLUMN_NAME_TITLE } ;
-
-        // The view IDs that will display the cursor columns, initialized to the TextView in
-        // noteslist_item.xml
-        int[] viewIDs = { android.R.id.text1 };
-
-        // Creates the backing adapter for the ListView.
-        SimpleCursorAdapter adapter
-            = new SimpleCursorAdapter(
-                      this,                             // The Context for the ListView
-                      R.layout.noteslist_item,          // Points to the XML for a list item
-                      cursor,                           // The cursor to get items from
-                      dataColumns,
-                      viewIDs
-              );
-
-        // Sets the ListView's adapter to be the cursor adapter that was just created.
+        // Used to map notes entries from the database to views
+        SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor,
+                new String[] { Notes.TITLE }, new int[] { android.R.id.text1 });
         setListAdapter(adapter);
     }
 
-    /**
-     * Called when the user clicks the device's Menu button the first time for
-     * this Activity. Android passes in a Menu object that is populated with items.
-     *
-     * Sets up a menu that provides the Insert option plus a list of alternative actions for
-     * this Activity. Other applications that want to handle notes can "register" themselves in
-     * Android by providing an intent filter that includes the category ALTERNATIVE and the
-     * mimeTYpe NotePad.Notes.CONTENT_TYPE. If they do this, the code in onCreateOptionsMenu()
-     * will add the Activity that contains the intent filter to its list of options. In effect,
-     * the menu will offer the user other applications that can handle notes.
-     * @param menu A Menu object, to which menu items should be added.
-     * @return True, always. The menu should be displayed.
-     */
     @Override
     public boolean onCreateOptionsMenu(Menu menu) {
         super.onCreateOptionsMenu(menu);
 
-        // Adds an Insert menu item
-        MenuItem menuItem = menu.add(
-            Menu.NONE,                    // No menu group.
-            MENU_ITEM_INSERT,             // Unique ID for this item.
-            Menu.NONE,                    // No order within the group.
-            R.string.menu_insert          // Displayed text for the menu item.
-        );
+        // This is our one standard application action -- inserting a
+        // new note into the list.
+        menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert)
+                .setShortcut('3', 'a')
+                .setIcon(android.R.drawable.ic_menu_add);
 
-        // Sets keyboard shortcuts for the menu item, either "3" or "a";
-        menuItem.setShortcut('3', 'a');
+        // If there is currently data in the clipboard, we can paste it
+        // as a new note.
+        mPasteItem = menu.add(0, MENU_ITEM_PASTE, 0, R.string.menu_paste)
+                .setShortcut('4', 'p');
 
-        // Sets the icon for the menu item
-        menuItem.setIcon(android.R.drawable.ic_menu_add);
-
-        // Generates any additional actions that can be performed on the
+        // Generate any additional actions that can be performed on the
         // overall list.  In a normal install, there are no additional
         // actions found here, but this allows other applications to extend
         // our menu with their own actions.
-
-        /* Creates a new Intent with the same incoming data and no defined action.
-         * It also sets its category to ALTERNATIVE. This prepares the Intent as a place
-         * to group alternative options in the menu.
-         */
         Intent intent = new Intent(null, getIntent().getData());
         intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+        menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0,
+                new ComponentName(this, NotesList.class), null, intent, 0, null);
 
-        /* Creates a ComponentName from the current Context and this Activity object's
-         * class object.
-         */
-        ComponentName component = new ComponentName(this, NotesList.class);
-
-        /*
-         * Adds any other activities that want to be alternatives for this view. In effect,
-         * any application can add itself as an alternative on the options menu.
-         */
-        menu.addIntentOptions(
-            Menu.CATEGORY_ALTERNATIVE,   // Add the options to the Alternatives group
-            Menu.NONE,                   // Do not use a unique ID
-            Menu.NONE,                   // No need to order the options
-            component,                   // The ComponentName of the Activity making the request.
-                                         // This Activity is excluded from the list of alternatives.
-            null,                        // No specific items are listed first.
-            intent,                      // The Intent to resolve to, in effect, an Intent listing
-                                         // the alternatives
-            Menu.NONE,                   // no flags are needed
-            null                         // Since no specifics were used, so a menu item array is
-                                         // not needed.
-        );
-
-        // Returns true so that the menu is displayed.
         return true;
     }
 
-    /**
-     * Called when the user clicks the device's Menu button any time after the first time for
-     * this Activity. This modifies the standard options menu that was set up previously.
-     * See onCreateOptionsMenu().
-     * @param menu The existing Menu object for this Activity.
-     * @return True, always. The menu should be displayed.
-     */
     @Override
     public boolean onPrepareOptionsMenu(Menu menu) {
         super.onPrepareOptionsMenu(menu);
 
-        // Does the displayed list of notes have any items in it?
+        // The paste menu item is enabled if there is data on the clipboard.
+        ClipboardManager clipboard = (ClipboardManager)
+                getSystemService(Context.CLIPBOARD_SERVICE);
+        if (clipboard.hasPrimaryClip()) {
+            mPasteItem.setEnabled(true);
+        } else {
+            mPasteItem.setEnabled(false);
+        }
+
         final boolean haveItems = getListAdapter().getCount() > 0;
 
-        /*
-         * If there are notes in the list, assumes that one of them is selected.
-         * Generates the menu options that can be performed on the current selection,
-         * which includes options from this application plus actions from other
-         * applications that "registered" themselves using an intent filter for the
-         * NotePad.Notes.CONTENT_TYPE mimeType.
-         */
-
-        // Modifies the current menu
+        // If there are any notes in the list (which implies that one of
+        // them is selected), then we need to generate the actions that
+        // can be performed on the current selection.  This will be a combination
+        // of our own specific actions along with any extensions that can be
+        // found.
         if (haveItems) {
-
-            /*
-             * Appends the selected item's row ID (note ID) to the the URI in the incoming Intent's
-             * data area. The incoming Intent at this point could only be GET_CONTENT, which means
-             * that the URI is for a single note, so this statement constructs a URI that will
-             * select a single note from the provider.
-             */
+            // This is the selected item.
             Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
 
-            /*
-             * Builds the menu. The EDIT action is always the first action in the list, so
-             * a specifics array is required, but only needs one element.
-             *
-             */
-
-            // Creates an array of "specifics", Intents that must appear before all other options
+            // Build menu...  always starts with the EDIT action...
             Intent[] specifics = new Intent[1];
-
-            // Sets the Intent of the specifics array to be EDIT on the note ID URI
             specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
-
-            // Creates an array of menu items. The result of mapping specifics to Intents is put
-            // into this array
             MenuItem[] items = new MenuItem[1];
 
-            // Creates an Intent with no defined action and the note ID URI as data
+            // ... is followed by whatever other actions are available...
             Intent intent = new Intent(null, uri);
-
-            /* Adds the category ALTERNATIVE to the Intent, with the note ID URI as its
-             * data. This prepares the Intent as a place to group alternative options in the
-             * menu.
-             */
             intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
+                    items);
 
-            /*
-             * Add alternatives to the menu
-             */
-            menu.addIntentOptions(
-                Menu.CATEGORY_ALTERNATIVE,  // Add the Intents as options in the alternatives group.
-                Menu.NONE,                  // A unique item ID is not required.
-                Menu.NONE,                  // The alternatives don't need to be in order.
-                null,                       // The caller's name is not excluded from the group.
-                specifics,                  // These specific options must appear first.
-                intent,                     // These Intent objects map to the options in specifics.
-                Menu.NONE,                  // No flags are required.
-                items                       // The menu items generated from the specifics-to-
-                                            // Intents mapping
-            );
-
-            // If the Edit menu item exists, adds shortcuts for it.
+            // Give a shortcut to the edit action.
             if (items[0] != null) {
-
-                // Sets the Edit menu item shortcut to numeric "1", letter "e"
                 items[0].setShortcut('1', 'e');
             }
         } else {
-            // If the list is empty, removes any existing alternative actions from the menu
             menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
         }
 
-        // Displays the menu
         return true;
     }
 
-    /**
-     * This method is called when the user selects an option from the menu, but no item
-     * in the list is selected. If the option was INSERT, then a new Intent is sent out with action
-     * ACTION_INSERT. The data from the incoming Intent is put into the new Intent. In effect,
-     * this triggers the NoteEditor activity in the NotePad application.
-     *
-     * If the item was not INSERT, then most likely it was an alternative option from another
-     * application. The parent method is called to process the item.
-     * @param item The menu item that was selected by the user
-     * @return True, if the INSERT menu item was selected; otherwise, the result of calling
-     * the parent method.
-     */
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
-
-        // Gets the ID of the selected item
         switch (item.getItemId()) {
-
-        // If the menu item is Insert
         case MENU_ITEM_INSERT:
-
-            /*
-             * Launches a new Activity using an Intent. The intent filter for the Activity
-             * has to have action ACTION_INSERT. No category is set, so DEFAULT is assumed.
-             * In effect, this starts the NoteEditor Activity in NotePad.
-             */
+            // Launch activity to insert a new item
             startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
-
-            // Returns true, so that no more processing is done.
+            return true;
+        case MENU_ITEM_PASTE:
+            // Launch activity to insert a new item
+            startActivity(new Intent(Intent.ACTION_PASTE, getIntent().getData()));
             return true;
         }
-
-        // If the menu item selected is not Insert, then this calls the regular processing to
-        // handle the item.
         return super.onOptionsItemSelected(item);
     }
 
-    /**
-     * This method is called when the user context-clicks a note in the list. NotesList registers
-     * itself as the handler for context menus in its ListView (this is done in onCreate()).
-     *
-     * The only available option is DELETE.
-     *
-     * Context-click is equivalent to long-press.
-     *
-     * @param menu A ContexMenu object to which items should be added.
-     * @param view The View for which the context menu is being constructed.
-     * @param menuInfo Data associated with view.
-     * @throws ClassCastException
-     */
     @Override
     public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
         AdapterView.AdapterContextMenuInfo info;
-
-        // Tries to get the position of the item in the ListView that was long-pressed.
         try {
-            // Casts the incoming data object into the type for AdapterView objects.
-            info = (AdapterView.AdapterContextMenuInfo) menuInfo;
-
+             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
         } catch (ClassCastException e) {
-
-            // If the menu object can't be cast, logs an error.
             Log.e(TAG, "bad menuInfo", e);
             return;
         }
 
-        /*
-         * Gets the data associated with the item at the selected position. getItem() returns
-         * whatever the backing adapter of the ListView has associated with the item. In NotesList,
-         * the adapter associated all of the data for a note with its list item. As a result,
-         * getItem() returns that data as a Cursor.
-         */
         Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
-
-        // If the cursor is empty, then for some reason the adapter can't get the data from the
-        // provider, so returns null to the caller.
         if (cursor == null) {
             // For some reason the requested item isn't available, do nothing
             return;
         }
 
-        // Finds the index of the title column in the Cursor
-        int titleIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
+        // Setup the menu header
+        menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
 
-        // Sets the menu header to be the title of the selected note.
-        menu.setHeaderTitle(cursor.getString(titleIndex));
+        // Add a menu item to copy the note
+        menu.add(0, MENU_ITEM_COPY, 0, R.string.menu_copy);
 
-        // Adds a menu item to the context menu
-        menu.add(
-            Menu.NONE,            // No grouping is needed for this menu
-            MENU_ITEM_DELETE,     // A unique ID for this menu item.
-            Menu.NONE,            // No ordering is necessary in this menu
-            R.string.menu_delete  // The resource ID for the string to display for this item.
-        );
+        // Add a menu item to delete the note
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
     }
-
-    /**
-     * This method is called when the user selects an item from the context menu
-     * (see onCreateContextMenu()). The only menu item that is actually handled is DELETE.
-     * Anything else is an alternative option, for which default handling should be done.
-     *
-     * @param item The selected menu item
-     * @return True if the menu item was DELETE, and no default processing is need, otherwise false,
-     * which triggers the default handling of the item.
-     * @throws ClassCastException
-     */
+        
     @Override
     public boolean onContextItemSelected(MenuItem item) {
-
-        // The data from the menu item.
         AdapterView.AdapterContextMenuInfo info;
-
-        /*
-         * Gets the extra info from the menu item. When an note in the Notes list is long-pressed, a
-         * context menu appears. The menu items for the menu automatically get the data
-         * associated with the note that was long-pressed. The data comes from the provider that
-         * backs the list.
-         *
-         * The note's data is passed to the context menu creation routine in a ContextMenuInfo
-         * object.
-         *
-         * When one of the context menu items is clicked, the same data is passed, along with the
-         * note ID, to onContextItemSelected() via the item parameter.
-         */
-
         try {
-            // Casts the data object in the item into the type for AdapterView objects.
-            info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
-
+             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
         } catch (ClassCastException e) {
-
-            // If the object can't be cast, logs an error
             Log.e(TAG, "bad menuInfo", e);
-
-            // Triggers default processing of the menu item.
             return false;
         }
 
-        /*
-         * Gets the menu item's ID and compares it to known actions. The only action that is
-         * implemented is DELETE (it is set in onCreateContextMenu()). The switch statement is
-         * used to facilitate adding other actions in the future.
-         */
         switch (item.getItemId()) {
             case MENU_ITEM_DELETE: {
-                // Appends the selected note's ID to the URI sent with the incoming Intent.
+                // Delete the note that the context menu is for
                 Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
-
-                // Deletes the note from the provider by passing in a URI in note ID format.
-                // Please see the introductory note about performing provider operations on the
-                // UI thread.
-                getContentResolver().delete(
-                    noteUri,  // The URI of the provider
-                    null,     // No where clause is needed, since only a single note ID is being
-                              // passed in.
-                    null      // No where clause is used, so no where arguments are needed.
-                );
-
-                // Returns to the caller and skips further processing.
+                getContentResolver().delete(noteUri, null, null);
                 return true;
             }
+//BEGIN_INCLUDE(copy)
+            case MENU_ITEM_COPY: {
+                // Copy the note that the context menu is for on to the clipboard
+                ClipboardManager clipboard = (ClipboardManager)
+                        getSystemService(Context.CLIPBOARD_SERVICE);
+                Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
+                clipboard.setPrimaryClip(new ClippedData(null, null, new ClippedData.Item(
+                        noteUri)));
+                return true;
+            }
+//END_INCLUDE(copy)
         }
-
-        // For menu items other than DELETE, returns to the caller for further processing.
         return false;
     }
 
-    /**
-     * This method is called when the user clicks a note in the displayed list.
-     *
-     * This method handles incoming actions of either PICK (get data from the provider) or
-     * GET_CONTENT (get or create data). If the incoming action is EDIT, this method sends a
-     * new Intent to start NoteEditor.
-     * @param l The ListView that contains the clicked item
-     * @param v The View of the individual item
-     * @param position The position of v in the displayed list
-     * @param id The row ID of the clicked item
-     */
     @Override
     protected void onListItemClick(ListView l, View v, int position, long id) {
-
-        // Constructs a new URI from the incoming URI and the row ID
         Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
-
-        // Gets the action from the incoming Intent
+        
         String action = getIntent().getAction();
-
-        // Handles requests for note data
         if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
-
-            // Sets the result to return to the component that called this Activity. The
-            // result contains the new URI
+            // The caller is waiting for us to return a note selected by
+            // the user.  The have clicked on one, so return it now.
             setResult(RESULT_OK, new Intent().setData(uri));
         } else {
-
-            // Sends out an Intent to start an Activity that can handle ACTION_EDIT. The
-            // Intent's data is the note ID URI. The effect is to call NoteEdit.
+            // Launch activity to view/edit the currently selected item
             startActivity(new Intent(Intent.ACTION_EDIT, uri));
         }
     }
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java b/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
index 3310de6..00eb314 100644
--- a/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
+++ b/samples/NotePad/src/com/example/android/notepad/NotesLiveFolder.java
@@ -18,91 +18,48 @@
 
 import android.app.Activity;
 import android.content.Intent;
-import android.content.Intent.ShortcutIconResource;
+import android.net.Uri;
 import android.os.Bundle;
 import android.provider.LiveFolders;
 
-/**
- * This Activity creates a live folder Intent and
- * sends it back to HOME. From the data in the Intent, HOME creates a live folder and displays
- * its icon in the Home view.
- * When the user clicks the icon, Home uses the data it got from the Intent to retrieve information
- * from a content provider and display it in a View.
- *
- * The intent filter for this Activity is set to ACTION_CREATE_LIVE_FOLDER, which
- * HOME sends in response to a long press and selection of Live Folder.
- */
 public class NotesLiveFolder extends Activity {
     /**
-     * All of the work is done in onCreate(). The Activity doesn't actually display a UI.
-     * Instead, it sets up an Intent and returns it to its caller (the HOME activity).
+     * The URI for the Notes Live Folder content provider.
      */
+    public static final Uri CONTENT_URI = Uri.parse("content://"
+            + NotePad.AUTHORITY + "/live_folders/notes");
+
+    public static final Uri NOTE_URI = Uri.parse("content://"
+            + NotePad.AUTHORITY + "/notes/#");
+
     @Override
     protected void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        /*
-         * Gets the incoming Intent and its action. If the incoming Intent was
-         * ACTION_CREATE_LIVE_FOLDER, then create an outgoing Intent with the
-         * necessary data and send back OK. Otherwise, send back CANCEL.
-         */
         final Intent intent = getIntent();
         final String action = intent.getAction();
 
         if (LiveFolders.ACTION_CREATE_LIVE_FOLDER.equals(action)) {
-            // Create a new Intent.
+            // Build the live folder intent.
             final Intent liveFolderIntent = new Intent();
 
-            /*
-             * The following statements put data into the outgoing Intent. Please see
-             * {@link android.provider.LiveFolders for a detailed description of these
-             * data values. From this data, HOME sets up a live folder.
-             */
-            // Sets the URI pattern for the content provider backing the folder.
-            liveFolderIntent.setData(NotePad.Notes.LIVE_FOLDER_URI);
-
-            // Adds the display name of the live folder as an Extra string.
-            String foldername = getString(R.string.live_folder_name);
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME, foldername);
-
-            // Adds the display icon of the live folder as an Extra resource.
-            ShortcutIconResource foldericon =
-                Intent.ShortcutIconResource.fromContext(this, R.drawable.live_folder_notes);
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON, foldericon);
-
-            // Add the display mode of the live folder as an integer. The specified
-            // mode causes the live folder to display as a list.
-            liveFolderIntent.putExtra(
-                    LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
+            liveFolderIntent.setData(CONTENT_URI);
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_NAME,
+                    getString(R.string.live_folder_name));
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_ICON,
+                    Intent.ShortcutIconResource.fromContext(this,
+                            R.drawable.live_folder_notes));
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_DISPLAY_MODE,
                     LiveFolders.DISPLAY_MODE_LIST);
+            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT,
+                    new Intent(Intent.ACTION_EDIT, NOTE_URI));
 
-            /*
-             * Adds a base action for items in the live folder list, as an Intent. When the
-             * user clicks an individual note in the list, the live folder fires this Intent.
-             *
-             * Its action is ACTION_EDIT, so it triggers the Note Editor activity. Its
-             * data is the URI pattern for a single note identified by its ID. The live folder
-             * automatically adds the ID value of the selected item to the URI pattern.
-             *
-             * As a result, Note Editor is triggered and gets a single note to retrieve by ID.
-             */
-            Intent returnIntent
-                    = new Intent(Intent.ACTION_EDIT, NotePad.Notes.CONTENT_ID_URI_PATTERN);
-            liveFolderIntent.putExtra(LiveFolders.EXTRA_LIVE_FOLDER_BASE_INTENT, returnIntent);
-
-            /* Creates an ActivityResult object to propagate back to HOME. Set its result indicator
-             * to OK, and sets the returned Intent to the live folder Intent that was just
-             * constructed.
-             */
+            // The result of this activity should be a live folder intent.
             setResult(RESULT_OK, liveFolderIntent);
-
         } else {
-            // If the original action was not ACTION_CREATE_LIVE_FOLDER, creates an
-            // ActivityResult with the indicator set to CANCELED, but do not return an Intent
             setResult(RESULT_CANCELED);
         }
-        // Closes the Activity. The ActivityObject is propagated back to the caller.
-        finish();
 
+        finish();
     }
 }
diff --git a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
index 4406262..50d38e5 100644
--- a/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
+++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
@@ -28,154 +28,88 @@
 import android.widget.EditText;
 
 /**
- * This Activity allows the user to edit a note's title. It displays a floating window
- * containing an EditText.
- *
- * NOTE: Notice that the provider operations in this Activity are taking place on the UI thread.
- * This is not a good practice. It is only done here to make the code more readable. A real
- * application should use the {@link android.content.AsyncQueryHandler}
- * or {@link android.os.AsyncTask} object to perform operations asynchronously on a separate thread.
+ * An activity that will edit the title of a note. Displays a floating
+ * window with a text field.
  */
 public class TitleEditor extends Activity implements View.OnClickListener {
 
     /**
-     * This is a special Intent action that means "edit the title of a note".
+     * This is a special intent action that means "edit the title of a note".
      */
     public static final String EDIT_TITLE_ACTION = "com.android.notepad.action.EDIT_TITLE";
 
-    // Creates a projection that returns the note ID and the note contents.
+    /**
+     * An array of the columns we are interested in.
+     */
     private static final String[] PROJECTION = new String[] {
-            NotePad.Notes._ID,
-            NotePad.Notes.COLUMN_NAME_TITLE,
+            NotePad.Notes._ID, // 0
+            NotePad.Notes.TITLE, // 1
     };
-    // The position of the title column in a Cursor returned by the provider.
+    /** Index of the title column */
     private static final int COLUMN_INDEX_TITLE = 1;
 
-    // A Cursor object that will contain the results of querying the provider for a note.
+    /**
+     * Cursor which will provide access to the note whose title we are editing.
+     */
     private Cursor mCursor;
 
-    // An EditText object for preserving the edited title.
+    /**
+     * The EditText field from our UI. Keep track of this so we can extract the
+     * text when we are finished.
+     */
     private EditText mText;
 
-    // A URI object for the note whose title is being edited.
+    /**
+     * The content URI to the note that's being edited.
+     */
     private Uri mUri;
 
-    /**
-     * This method is called by Android when the Activity is first started. From the incoming
-     * Intent, it determines what kind of editing is desired, and then does it.
-     */
     @Override
     public void onCreate(Bundle savedInstanceState) {
         super.onCreate(savedInstanceState);
 
-        // Set the View for this Activity object's UI.
         setContentView(R.layout.title_editor);
 
-        // Get the Intent that activated this Activity, and from it get the URI of the note whose
-        // title we need to edit.
+        // Get the uri of the note whose title we want to edit
         mUri = getIntent().getData();
 
-        /*
-         * Using the URI passed in with the triggering Intent, gets the note.
-         *
-         * Note: This is being done on the UI thread. It will block the thread until the query
-         * completes. In a sample app, going against a simple provider based on a local database,
-         * the block will be momentary, but in a real app you should use
-         * android.content.AsyncQueryHandler or android.os.AsyncTask.
-         */
-        mCursor = managedQuery(
-            mUri,        // The URI for the note that is to be retrieved.
-            PROJECTION,  // The columns to retrieve
-            null,        // No selection criteria are used, so no where columns are needed.
-            null,        // No where columns are used, so no where values are needed.
-            null         // No sort order is needed.
-        );
+        // Get a cursor to access the note
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
 
-        // Sets up a listener for the EditText. Gets the EditText by its ID, then sets its
-        // onClickListener to this Activity.
+        // Set up click handlers for the text field and button
         mText = (EditText) this.findViewById(R.id.title);
         mText.setOnClickListener(this);
-
-        // Sets up a listener for the OK button. Gets the Button by its ID, then sets its
-        // onClickListener to this Activity.
+        
         Button b = (Button) findViewById(R.id.ok);
         b.setOnClickListener(this);
     }
 
-    /**
-     * This method is called when the Activity is about to come to the foreground. This happens
-     * when the Activity comes to the top of the task stack, OR when it is first starting.
-     *
-     * Displays the current title for the selected note.
-     */
     @Override
     protected void onResume() {
         super.onResume();
 
-        // Verifies that the query made in onCreate() actually worked. If it worked, then the
-        // Cursor object is not null. If it is *empty*, then mCursor.getCount() == 0.
+        // Initialize the text with the title column from the cursor
         if (mCursor != null) {
-
-            // The Cursor was just retrieved, so its index is set to one record *before* the first
-            // record retrieved. This moves it to the first record.
             mCursor.moveToFirst();
-
-            // Displays the current title text in the EditText object.
             mText.setText(mCursor.getString(COLUMN_INDEX_TITLE));
         }
     }
 
-    /**
-     * This method is called when the Activity loses focus.
-     *
-     * For Activity objects that edit information, onPause() may be the one place where changes are
-     * saved. The Android application model is predicated on the idea that "save" and "exit" aren't
-     * required actions. When users navigate away from an Activity, they shouldn't have to go back
-     * to it to complete their work. The act of going away should save everything and leave the
-     * Activity in a state where Android can destroy it if necessary.
-     *
-     * Updates the note with the text currently in the text box.
-     */
     @Override
     protected void onPause() {
         super.onPause();
 
-        // Verifies that the query made in onCreate() actually worked. If it worked, then the
-        // Cursor object is not null. If it is *empty*, then mCursor.getCount() == 0.
         if (mCursor != null) {
-
-            // Creates a values map for updating the provider.
+            // Write the title back to the note 
             ContentValues values = new ContentValues();
-
-            // In the values map, sets the title to the current contents of the edit box.
-            values.put(Notes.COLUMN_NAME_TITLE, mText.getText().toString());
-
-            /*
-             * Updates the provider with the note's new title.
-             *
-             * Note: This is being done on the UI thread. It will block the thread until the
-             * update completes. In a sample app, going against a simple provider based on a
-             * local database, the block will be momentary, but in a real app you should use
-             * android.content.AsyncQueryHandler or android.os.AsyncTask.
-             */
-            getContentResolver().update(
-                mUri,    // The URI for the note to update.
-                values,  // The values map containing the columns to update and the values to use.
-                null,    // No selection criteria is used, so no "where" columns are needed.
-                null     // No "where" columns are used, so no "where" values are needed.
-            );
+            values.put(Notes.TITLE, mText.getText().toString());
+            getContentResolver().update(mUri, values, null, null);
         }
     }
 
-    /**
-     * This method is called when the user clicks anywhere in the title text box.
-     *
-     * It calls finish(), which immediately triggers the onPause() method in this Activity. In
-     * turn, onPause() saves the text currently in the title text box to the note.
-     */
     public void onClick(View v) {
-        // Calls finish to force the Activity to shut down. In the lifecycle, this forces a call to
-        // onPause(), which saves the work the user has done.
+        // When the user clicks, just finish this activity.
+        // onPause will be called, and we save our data there.
         finish();
     }
 }
diff --git a/samples/NotePad/src/com/google/provider/NotePad.java b/samples/NotePad/src/com/google/provider/NotePad.java
new file mode 100644
index 0000000..f8de69b
--- /dev/null
+++ b/samples/NotePad/src/com/google/provider/NotePad.java
@@ -0,0 +1,65 @@
+/* 
+ * 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.
+ */
+
+package com.google.provider;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Convenience definitions for NotePadProvider
+ */
+public final class NotePad {
+    /**
+     * Notes table
+     */
+    public static final class Notes implements BaseColumns {
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI
+                = Uri.parse("content://com.google.provider.NotePad/notes");
+
+        /**
+         * The default sort order for this table
+         */
+        public static final String DEFAULT_SORT_ORDER = "modified DESC";
+
+        /**
+         * The title of the note
+         * <P>Type: TEXT</P>
+         */
+        public static final String TITLE = "title";
+
+        /**
+         * The note itself
+         * <P>Type: TEXT</P>
+         */
+        public static final String NOTE = "note";
+
+        /**
+         * The timestamp for when the note was created
+         * <P>Type: INTEGER (long)</P>
+         */
+        public static final String CREATED_DATE = "created";
+
+        /**
+         * The timestamp for when the note was last modified
+         * <P>Type: INTEGER (long)</P>
+         */
+        public static final String MODIFIED_DATE = "modified";
+    }
+}
diff --git a/samples/NotePad/tests/Android.mk b/samples/NotePad/tests/Android.mk
index 1e4af66..43efafc 100644
--- a/samples/NotePad/tests/Android.mk
+++ b/samples/NotePad/tests/Android.mk
@@ -5,7 +5,7 @@
 
 LOCAL_JAVA_LIBRARIES := android.test.runner
 
-LOCAL_PACKAGE_NAME := NotePadTest
+LOCAL_PACKAGE_NAME := NotePadTests
 
 LOCAL_MODULE_TAGS := tests
 
diff --git a/samples/NotePad/tests/AndroidManifest.xml b/samples/NotePad/tests/AndroidManifest.xml
index 90860d1..afd502b 100644
--- a/samples/NotePad/tests/AndroidManifest.xml
+++ b/samples/NotePad/tests/AndroidManifest.xml
@@ -4,51 +4,29 @@
      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.
 -->
-<!--
-    If you use this file as a template in your own test package, you must change
-    the package name from "com.android.example.notepad.test" to one that you own or have
-    control over.
-    Notice that the package name is not necessarily related to any of the Java package
-    identifiers used in this application.
--->
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="com.example.android.notepad.test"
-    android:versionCode="2"
-    android:versionName="2.0">
 
-    <!--
-        Defines an application element. The XML DTD for Android requires
-        the &lt;uses-library&gt; element to appear within an &lt;application&gt; element.
-        In all other respects, this manifest declares a test package rather than a
-        regular Android application.
-    -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
+      package="com.example.android.notepad.tests">
+    
+    <!-- We add an application tag here just so that we can indicate that
+         this package needs to link against the android.test library,
+         which is needed when building test cases. -->    
     <application>
-        <!--
-            Specifies a code library that Android must load along with this package.
-            The library contains the instrumented test runner.
-         -->
         <uses-library android:name="android.test.runner" />
     </application>
 
-    <!--
-        Specifies the test runner that will run the test cases in this package.
-        The android:name attribute specifies the test runner. The android:targetPackage specifies
-        the Android package name of the application under test.
-        In general, Android handles an instrumentation element by loading the class in the
-        android:name attribute as an Instrumentation object before loading the package in which the
-        instrumentation element occurs and before the package specified in android:targetPackage.
-     -->
-    <instrumentation
-        android:name="android.test.InstrumentationTestRunner"
-        android:targetPackage="com.example.android.notepad">
-    </instrumentation>
+  <instrumentation android:name="android.test.InstrumentationTestRunner"
+      android:targetPackage="com.example.android.notepad"
+      android:label="NotePad sample tests">
+  </instrumentation>  
+  
 </manifest>
diff --git a/samples/NotePad/tests/_index.html b/samples/NotePad/tests/_index.html
deleted file mode 100644
index 29a3d83..0000000
--- a/samples/NotePad/tests/_index.html
+++ /dev/null
@@ -1,97 +0,0 @@
-<p>
-    This sample contains a test package that demonstrates
-    <a href="../../../reference/android/content/ContentProvider.html">ContentProvider</a> testing
-    and <a href="../../../reference/android/app/Activity.html">Activity</a> testing. It is a test
-    of the <a href="../NotePad/index.html">Note Pad</a> sample application.
-</p>
-<h2>Test Package</h2>
-<p>
-    The test package project is located in the <code>tests/</code> subdirectory of the
-    Note Pad project. It provides an example of the structure of a test package project,
-    and it contains a example of a <a href="AndroidManifest.html">
-    <code>AndroidManifest.xml</code></a> file for a test package.
-    The package uses <a href="../../../reference/android/test/InstrumentationTestRunner.html">
-    <code>InstrumentationTestRunner</code></a> as its test runner.
-</p>
-<p>
-    The <a href="AndroidManifest.html">manifest</a> for this test package contains an
-    <code>&lt;instrumentation&gt;</code> element that links the test package
-    with the application under test. Specifically, the element's <code>android:name</code>
-    attribute specifies that Android should use <code>InstrumentationTestRunner</code> to
-    control the classes in this package. The <code>android:targetPackage</code> attribute
-    targets <code>com.android.example.notepad</code> as the Android package that contains the
-    application under test.
-</p>
-<h2>ContentProvider Test</h2>
-<p>
-    The ContentProvider test suite is contained in the single test case class
-    <a href="src/com/example/android/notepad/NotePadProviderTest.html">
-    <code>NotePadProviderTest</code></a>. This class extends
-    <a href="../../../reference/android/test/ProviderTestCase2.html"><code>ProviderTestCase2</code>
-    </a>, which extends the JUnit
-    <a href="../../../reference/junit/framework/TestCase.html"><code>TestCase</code></a> class and
-    also provides methods and objects that facilitate ContentProvider testing.
-</p>
-<p>
-    Although the sample test suite for ContentProvider testing uses a single test case class,
-    you may use as many test case classes as you wish, and each class can contain as many
-    test methods as you wish.
-</p>
-<h3>ContentProvider test methods</h3>
-<p>
-    <code>NotePadProviderTest</code></a> contains the following methods:
-</p>
-    <ul>
-        <li>
-            Test setup: The <code>setUp()</code> method re-initializes the test environment
-            (the test fixutre) before each test is run. The call to <code>super.setUp()</code>
-            creates a test context and test resolver, and creates a local instance of the
-            provider under test. By creating the provider, the super constructor also tests the
-            provider's <code>onCreate()</code> method, which is called during the provider's
-            initialization.
-        <p>
-            The <code>setUp()</code> method then gets a handle to the local provider's
-            underlying database. This is used to set up test data in succeeding tests.
-        </p>
-        </li>
-        <li>
-            Test tear down: The <code>tearDown()</code> method calls <code>super.tearDown()</code>,
-            which cleans up left-over object references to prevent memory leaks.
-        </li>
-        <li>
-            Test database creation: The <code>insertData()</code> helper method adds test data
-            to the local provider. Individual test methods call <code>insertData()</code>
-            when they need to set up a test fixture that contains valid data. This data is not
-            inserted during <code>setUp()</code>, because some tests expect an empty database.
-        </li>
-        <li>
-            Content provider unit tests: The test package shows how to unit
-            test a content provider's getType, query, insert, delete, and update
-            methods against all the content Uris that the provider offers.
-            Only a subset of all the possible unit tests is included.
-        </li>
-    </ul>
-<h2>Activity Test</h2>
-<p>
-    The Activity test suite is contained in the single test case class
-    <a href="src/com/example/android/notepad/NotePadActivityTest.html">
-    <code>NotePadActivityTest</code></a>. This class extends
-    <a href="../../../reference/android/test/ActivityInstrumentationTestCase2.html">
-    <code>ActivityInstrumentationTestCase2</code>, which provides the JUnit test framework and
-    also provides instrumentation methods that facilitate Activity testing.
-</p>
-<p>
-    The <code>NotePadActivityTest</code> test class contains a single assertion,
-    <code>testActivityTestCaseSetUpProperly()</code>. This assertion calls
-    <a href="../../../reference/android/test/ActivityInstrumentationTestCase2.html#getActivity()">
-    <code>Activity.getActivity()</code> and then fails if the result is <code>null</code>,
-    indicating that the test was unable to start the Activity under test.
-</p>
-<img
-    src="../images/sample_note.png"
-    alt="The user interface for a single note in the Note Pad sample app"
-    style="height:230px"/>
-<img
-    src="../images/sample_notepadtest_junit.png"
-    alt="Results of a successful run of the NotePadTest test package in Eclipse"
-    style="height:230px"/>
diff --git a/samples/NotePad/tests/build.properties b/samples/NotePad/tests/build.properties
new file mode 100644
index 0000000..e0c39de
--- /dev/null
+++ b/samples/NotePad/tests/build.properties
@@ -0,0 +1 @@
+tested.project.dir=..
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java
deleted file mode 100644
index 4790e42..0000000
--- a/samples/NotePad/tests/src/com/example/android/notepad/NotePadProviderTest.java
+++ /dev/null
@@ -1,585 +0,0 @@
-/*
- * Copyright (C) 2010 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.example.android.notepad;
-
-import android.content.ContentUris;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.database.sqlite.SQLiteDatabase;
-import android.net.Uri;
-import android.test.ProviderTestCase2;
-import android.test.mock.MockContentResolver;
-
-import java.util.Calendar;
-import java.util.GregorianCalendar;
-
-/*
- */
-/**
- * This class tests the content provider for the Note Pad sample application.
- *
- * To learn how to run an entire test package or one of its classes, please see
- * "Testing in Eclipse, with ADT" or "Testing in Other IDEs" in the Developer Guide.
- */
-public class NotePadProviderTest extends ProviderTestCase2<NotePadProvider> {
-
-    // A URI that the provider does not offer, for testing error handling.
-    private static final Uri INVALID_URI =
-        Uri.withAppendedPath(NotePad.Notes.CONTENT_URI, "invalid");
-
-    // Contains a reference to the mocked content resolver for the provider under test.
-    private MockContentResolver mMockResolver;
-
-    // Contains an SQLite database, used as test data
-    private SQLiteDatabase mDb;
-
-    // Contains the test data, as an array of NoteInfo instances.
-    private final NoteInfo[] TEST_NOTES = {
-        new NoteInfo("Note0", "This is note 0"),
-        new NoteInfo("Note1", "This is note 1"),
-        new NoteInfo("Note2", "This is note 2"),
-        new NoteInfo("Note3", "This is note 3"),
-        new NoteInfo("Note4", "This is note 4"),
-        new NoteInfo("Note5", "This is note 5"),
-        new NoteInfo("Note6", "This is note 6"),
-        new NoteInfo("Note7", "This is note 7"),
-        new NoteInfo("Note8", "This is note 8"),
-        new NoteInfo("Note9", "This is note 9") };
-
-    // Number of milliseconds in one day (milliseconds * seconds * minutes * hours)
-    private static final long ONE_DAY_MILLIS = 1000 * 60 * 60 * 24;
-
-    // Number of milliseconds in one week
-    private static final long ONE_WEEK_MILLIS = ONE_DAY_MILLIS * 7;
-
-    // Creates a calendar object equal to January 1, 2010 at 12 midnight
-    private static final GregorianCalendar TEST_CALENDAR =
-        new GregorianCalendar(2010, Calendar.JANUARY, 1, 0, 0, 0);
-
-    // Stores a timestamp value, set to an arbitrary starting point
-    private final static long START_DATE = TEST_CALENDAR.getTimeInMillis();
-
-    /*
-     * Constructor for the test case class.
-     * Calls the super constructor with the class name of the provider under test and the
-     * authority name of the provider.
-     */
-    public NotePadProviderTest() {
-        super(NotePadProvider.class, NotePad.AUTHORITY);
-    }
-
-
-    /*
-     * Sets up the test environment before each test method. Creates a mock content resolver,
-     * gets the provider under test, and creates a new database for the provider.
-     */
-    @Override
-    protected void setUp() throws Exception {
-        // Calls the base class implementation of this method.
-        super.setUp();
-
-        // Gets the resolver for this test.
-        mMockResolver = getMockContentResolver();
-
-        /*
-         * Gets a handle to the database underlying the provider. Gets the provider instance
-         * created in super.setUp(), gets the DatabaseOpenHelper for the provider, and gets
-         * a database object from the helper.
-         */
-        mDb = getProvider().getOpenHelperForTest().getWritableDatabase();
-    }
-
-    /*
-     *  This method is called after each test method, to clean up the current fixture. Since
-     *  this sample test case runs in an isolated context, no cleanup is necessary.
-     */
-    @Override
-    protected void tearDown() throws Exception {
-        super.tearDown();
-    }
-
-    /*
-     * Sets up test data.
-     * The test data is in an SQL database. It is created in setUp() without any data,
-     * and populated in insertData if necessary.
-     */
-    private void insertData() {
-        // Creates an instance of the ContentValues map type expected by database insertions
-        ContentValues values = new ContentValues();
-
-        // Sets up test data
-        for (int index = 0; index < TEST_NOTES.length; index++) {
-
-            // Set the creation and modification date for the note
-            TEST_NOTES[index].setCreationDate(START_DATE + (index * ONE_DAY_MILLIS));
-            TEST_NOTES[index].setModificationDate(START_DATE + (index * ONE_WEEK_MILLIS));
-
-            // Adds a record to the database.
-            mDb.insertOrThrow(
-                NotePad.Notes.TABLE_NAME,             // the table name for the insert
-                NotePad.Notes.COLUMN_NAME_TITLE,      // column set to null if empty values map
-                TEST_NOTES[index].getContentValues()  // the values map to insert
-            );
-        }
-    }
-
-    /*
-     * Tests the provider's publicly available URIs. If the URI is not one that the provider
-     * understands, the provider should throw an exception. It also tests the provider's getType()
-     * method for each URI, which should return the MIME type associated with the URI.
-     */
-    public void testUriAndGetType() {
-        // Tests the MIME type for the notes table URI.
-        String mimeType = mMockResolver.getType(NotePad.Notes.CONTENT_URI);
-        assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
-
-        // Tests the MIME type for the live folder URI.
-        mimeType = mMockResolver.getType(NotePad.Notes.LIVE_FOLDER_URI);
-        assertEquals(NotePad.Notes.CONTENT_TYPE, mimeType);
-
-        // Creates a URI with a pattern for note ids. The id doesn't have to exist.
-        Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
-
-        // Gets the note ID URI MIME type.
-        mimeType = mMockResolver.getType(noteIdUri);
-        assertEquals(NotePad.Notes.CONTENT_ITEM_TYPE, mimeType);
-
-        // Tests an invalid URI. This should throw an IllegalArgumentException.
-        mimeType = mMockResolver.getType(INVALID_URI);
-    }
-
-    /*
-     * Tests the provider's public API for querying data in the table, using the URI for
-     * a dataset of records.
-     */
-    public void testQueriesOnNotesUri() {
-        // Defines a projection of column names to return for a query
-        final String[] TEST_PROJECTION = {
-            NotePad.Notes.COLUMN_NAME_TITLE,
-            NotePad.Notes.COLUMN_NAME_NOTE,
-            NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE
-        };
-
-        // Defines a selection column for the query. When the selection columns are passed
-        // to the query, the selection arguments replace the placeholders.
-        final String TITLE_SELECTION = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
-
-        // Defines the selection columns for a query.
-        final String SELECTION_COLUMNS =
-            TITLE_SELECTION + " OR " + TITLE_SELECTION + " OR " + TITLE_SELECTION;
-
-         // Defines the arguments for the selection columns.
-        final String[] SELECTION_ARGS = { "Note0", "Note1", "Note5" };
-
-         // Defines a query sort order
-        final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
-
-        // Query subtest 1.
-        // If there are no records in the table, the returned cursor from a query should be empty.
-        Cursor cursor = mMockResolver.query(
-            NotePad.Notes.CONTENT_URI,  // the URI for the main data table
-            null,                       // no projection, get all columns
-            null,                       // no selection criteria, get all records
-            null,                       // no selection arguments
-            null                        // use default sort order
-        );
-
-         // Asserts that the returned cursor contains no records
-        assertEquals(0, cursor.getCount());
-
-         // Query subtest 2.
-         // If the table contains records, the returned cursor from a query should contain records.
-
-        // Inserts the test data into the provider's underlying data source
-        insertData();
-
-        // Gets all the columns for all the rows in the table
-        cursor = mMockResolver.query(
-            NotePad.Notes.CONTENT_URI,  // the URI for the main data table
-            null,                       // no projection, get all columns
-            null,                       // no selection criteria, get all records
-            null,                       // no selection arguments
-            null                        // use default sort order
-        );
-
-        // Asserts that the returned cursor contains the same number of rows as the size of the
-        // test data array.
-        assertEquals(TEST_NOTES.length, cursor.getCount());
-
-        // Query subtest 3.
-        // A query that uses a projection should return a cursor with the same number of columns
-        // as the projection, with the same names, in the same order.
-        Cursor projectionCursor = mMockResolver.query(
-              NotePad.Notes.CONTENT_URI,  // the URI for the main data table
-              TEST_PROJECTION,            // get the title, note, and mod date columns
-              null,                       // no selection columns, get all the records
-              null,                       // no selection criteria
-              null                        // use default the sort order
-        );
-
-        // Asserts that the number of columns in the cursor is the same as in the projection
-        assertEquals(TEST_PROJECTION.length, projectionCursor.getColumnCount());
-
-        // Asserts that the names of the columns in the cursor and in the projection are the same.
-        // This also verifies that the names are in the same order.
-        assertEquals(TEST_PROJECTION[0], projectionCursor.getColumnName(0));
-        assertEquals(TEST_PROJECTION[1], projectionCursor.getColumnName(1));
-        assertEquals(TEST_PROJECTION[2], projectionCursor.getColumnName(2));
-
-        // Query subtest 4
-        // A query that uses selection criteria should return only those rows that match the
-        // criteria. Use a projection so that it's easy to get the data in a particular column.
-        projectionCursor = mMockResolver.query(
-            NotePad.Notes.CONTENT_URI, // the URI for the main data table
-            TEST_PROJECTION,           // get the title, note, and mod date columns
-            SELECTION_COLUMNS,         // select on the title column
-            SELECTION_ARGS,            // select titles "Note0", "Note1", or "Note5"
-            SORT_ORDER                 // sort ascending on the title column
-        );
-
-        // Asserts that the cursor has the same number of rows as the number of selection arguments
-        assertEquals(SELECTION_ARGS.length, projectionCursor.getCount());
-
-        int index = 0;
-
-        while (projectionCursor.moveToNext()) {
-
-            // Asserts that the selection argument at the current index matches the value of
-            // the title column (column 0) in the current record of the cursor
-            assertEquals(SELECTION_ARGS[index], projectionCursor.getString(0));
-
-            index++;
-        }
-
-        // Asserts that the index pointer is now the same as the number of selection arguments, so
-        // that the number of arguments tested is exactly the same as the number of rows returned.
-        assertEquals(SELECTION_ARGS.length, index);
-
-    }
-
-    /*
-     * Tests queries against the provider, using the note id URI. This URI encodes a single
-     * record ID. The provider should only return 0 or 1 record.
-     */
-    public void testQueriesOnNoteIdUri() {
-      // Defines the selection column for a query. The "?" is replaced by entries in the
-      // selection argument array
-      final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
-
-      // Defines the argument for the selection column.
-      final String[] SELECTION_ARGS = { "Note1" };
-
-      // A sort order for the query.
-      final String SORT_ORDER = NotePad.Notes.COLUMN_NAME_TITLE + " ASC";
-
-      // Creates a projection includes the note id column, so that note id can be retrieved.
-      final String[] NOTE_ID_PROJECTION = {
-           NotePad.Notes._ID,                 // The Notes class extends BaseColumns,
-                                              // which includes _ID as the column name for the
-                                              // record's id in the data model
-           NotePad.Notes.COLUMN_NAME_TITLE};  // The note's title
-
-      // Query subtest 1.
-      // Tests that a query against an empty table returns null.
-
-      // Constructs a URI that matches the provider's notes id URI pattern, using an arbitrary
-      // value of 1 as the note ID.
-      Uri noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, 1);
-
-      // Queries the table with the notes ID URI. This should return an empty cursor.
-      Cursor cursor = mMockResolver.query(
-          noteIdUri, // URI pointing to a single record
-          null,      // no projection, get all the columns for each record
-          null,      // no selection criteria, get all the records in the table
-          null,      // no need for selection arguments
-          null       // default sort, by ascending title
-      );
-
-      // Asserts that the cursor is null.
-      assertEquals(0,cursor.getCount());
-
-      // Query subtest 2.
-      // Tests that a query against a table containing records returns a single record whose ID
-      // is the one requested in the URI provided.
-
-      // Inserts the test data into the provider's underlying data source.
-      insertData();
-
-      // Queries the table using the URI for the full table.
-      cursor = mMockResolver.query(
-          NotePad.Notes.CONTENT_URI, // the base URI for the table
-          NOTE_ID_PROJECTION,        // returns the ID and title columns of rows
-          SELECTION_COLUMNS,         // select based on the title column
-          SELECTION_ARGS,            // select title of "Note1"
-          SORT_ORDER                 // sort order returned is by title, ascending
-      );
-
-      // Asserts that the cursor contains only one row.
-      assertEquals(1, cursor.getCount());
-
-      // Moves to the cursor's first row, and asserts that this did not fail.
-      assertTrue(cursor.moveToFirst());
-
-      // Saves the record's note ID.
-      int inputNoteId = cursor.getInt(0);
-
-      // Builds a URI based on the provider's content ID URI base and the saved note ID.
-      noteIdUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_ID_URI_BASE, inputNoteId);
-
-      // Queries the table using the content ID URI, which returns a single record with the
-      // specified note ID, matching the selection criteria provided.
-      cursor = mMockResolver.query(noteIdUri, // the URI for a single note
-          NOTE_ID_PROJECTION,                 // same projection, get ID and title columns
-          SELECTION_COLUMNS,                  // same selection, based on title column
-          SELECTION_ARGS,                     // same selection arguments, title = "Note1"
-          SORT_ORDER                          // same sort order returned, by title, ascending
-      );
-
-      // Asserts that the cursor contains only one row.
-      assertEquals(1, cursor.getCount());
-
-      // Moves to the cursor's first row, and asserts that this did not fail.
-      assertTrue(cursor.moveToFirst());
-
-      // Asserts that the note ID passed to the provider is the same as the note ID returned.
-      assertEquals(inputNoteId, cursor.getInt(0));
-    }
-
-    /*
-     *  Tests inserts into the data model.
-     */
-    public void testInserts() {
-        // Creates a new note instance with ID of 30.
-        NoteInfo note = new NoteInfo(
-            "Note30", // the note's title
-            "Test inserting a note" // the note's content
-        );
-
-        // Sets the note's creation and modification times
-        note.setCreationDate(START_DATE + (10 * ONE_DAY_MILLIS));
-        note.setModificationDate(START_DATE + (2 * ONE_WEEK_MILLIS));
-
-        // Insert subtest 1.
-        // Inserts a row using the new note instance.
-        // No assertion will be done. The insert() method either works or throws an Exception
-        Uri rowUri = mMockResolver.insert(
-            NotePad.Notes.CONTENT_URI,  // the main table URI
-            note.getContentValues()     // the map of values to insert as a new record
-        );
-
-        // Parses the returned URI to get the note ID of the new note. The ID is used in subtest 2.
-        long noteId = ContentUris.parseId(rowUri);
-
-        // Does a full query on the table. Since insertData() hasn't yet been called, the
-        // table should only contain the record just inserted.
-        Cursor cursor = mMockResolver.query(
-            NotePad.Notes.CONTENT_URI, // the main table URI
-            null,                      // no projection, return all the columns
-            null,                      // no selection criteria, return all the rows in the model
-            null,                      // no selection arguments
-            null                       // default sort order
-        );
-
-        // Asserts that there should be only 1 record.
-        assertEquals(1, cursor.getCount());
-
-        // Moves to the first (and only) record in the cursor and asserts that this worked.
-        assertTrue(cursor.moveToFirst());
-
-        // Since no projection was used, get the column indexes of the returned columns
-        int titleIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_TITLE);
-        int noteIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_NOTE);
-        int crdateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_CREATE_DATE);
-        int moddateIndex = cursor.getColumnIndex(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE);
-
-        // Tests each column in the returned cursor against the data that was inserted, comparing
-        // the field in the NoteInfo object to the data at the column index in the cursor.
-        assertEquals(note.title, cursor.getString(titleIndex));
-        assertEquals(note.note, cursor.getString(noteIndex));
-        assertEquals(note.createDate, cursor.getLong(crdateIndex));
-        assertEquals(note.modDate, cursor.getLong(moddateIndex));
-
-        // Insert subtest 2.
-        // Tests that we can't insert a record whose id value already exists.
-
-        // Defines a ContentValues object so that the test can add a note ID to it.
-        ContentValues values = note.getContentValues();
-
-        // Adds the note ID retrieved in subtest 1 to the ContentValues object.
-        values.put(NotePad.Notes._ID, (int) noteId);
-
-        // Tries to insert this record into the table. This should fail and drop into the
-        // catch block. If it succeeds, issue a failure message.
-        try {
-            rowUri = mMockResolver.insert(NotePad.Notes.CONTENT_URI, values);
-            fail("Expected insert failure for existing record but insert succeeded.");
-        } catch (Exception e) {
-          // succeeded, so do nothing.
-        }
-    }
-
-    /*
-     * Tests deletions from the data model.
-     */
-    public void testDeletes() {
-        // Subtest 1.
-        // Tries to delete a record from a data model that is empty.
-
-        // Sets the selection column to "title"
-        final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
-
-        // Sets the selection argument "Note0"
-        final String[] SELECTION_ARGS = { "Note0" };
-
-        // Tries to delete rows matching the selection criteria from the data model.
-        int rowsDeleted = mMockResolver.delete(
-            NotePad.Notes.CONTENT_URI, // the base URI of the table
-            SELECTION_COLUMNS,         // select based on the title column
-            SELECTION_ARGS             // select title = "Note0"
-        );
-
-        // Assert that the deletion did not work. The number of deleted rows should be zero.
-        assertEquals(0, rowsDeleted);
-
-        // Subtest 2.
-        // Tries to delete an existing record. Repeats the previous subtest, but inserts data first.
-
-        // Inserts data into the model.
-        insertData();
-
-        // Uses the same parameters to try to delete the row with title "Note0"
-        rowsDeleted = mMockResolver.delete(
-            NotePad.Notes.CONTENT_URI, // the base URI of the table
-            SELECTION_COLUMNS,         // same selection column, "title"
-            SELECTION_ARGS             // same selection arguments, title = "Note0"
-        );
-
-        // The number of deleted rows should be 1.
-        assertEquals(1, rowsDeleted);
-
-        // Tests that the record no longer exists. Tries to get it from the table, and
-        // asserts that nothing was returned.
-
-        // Queries the table with the same selection column and argument used to delete the row.
-        Cursor cursor = mMockResolver.query(
-            NotePad.Notes.CONTENT_URI, // the base URI of the table
-            null,                      // no projection, return all columns
-            SELECTION_COLUMNS,         // select based on the title column
-            SELECTION_ARGS,            // select title = "Note0"
-            null                       // use the default sort order
-        );
-
-        // Asserts that the cursor is empty since the record had already been deleted.
-        assertEquals(0, cursor.getCount());
-    }
-
-    /*
-     * Tests updates to the data model.
-     */
-    public void testUpdates() {
-        // Selection column for identifying a record in the data model.
-        final String SELECTION_COLUMNS = NotePad.Notes.COLUMN_NAME_TITLE + " = " + "?";
-
-        // Selection argument for the selection column.
-        final String[] selectionArgs = { "Note1" };
-
-        // Defines a map of column names and values
-        ContentValues values = new ContentValues();
-
-        // Subtest 1.
-        // Tries to update a record in an empty table.
-
-        // Sets up the update by putting the "note" column and a value into the values map.
-        values.put(NotePad.Notes.COLUMN_NAME_NOTE, "Testing an update with this string");
-
-        // Tries to update the table
-        int rowsUpdated = mMockResolver.update(
-            NotePad.Notes.CONTENT_URI,  // the URI of the data table
-            values,                     // a map of the updates to do (column title and value)
-            SELECTION_COLUMNS,           // select based on the title column
-            selectionArgs               // select "title = Note1"
-        );
-
-        // Asserts that no rows were updated.
-        assertEquals(0, rowsUpdated);
-
-        // Subtest 2.
-        // Builds the table, and then tries the update again using the same arguments.
-
-        // Inserts data into the model.
-        insertData();
-
-        //  Does the update again, using the same arguments as in subtest 1.
-        rowsUpdated = mMockResolver.update(
-            NotePad.Notes.CONTENT_URI,   // The URI of the data table
-            values,                      // the same map of updates
-            SELECTION_COLUMNS,            // same selection, based on the title column
-            selectionArgs                // same selection argument, to select "title = Note1"
-        );
-
-        // Asserts that only one row was updated. The selection criteria evaluated to
-        // "title = Note1", and the test data should only contain one row that matches that.
-        assertEquals(1, rowsUpdated);
-    }
-
-    // A utility for converting note data to a ContentValues map.
-    private static class NoteInfo {
-        String title;
-        String note;
-        long createDate;
-        long modDate;
-
-        /*
-         * Constructor for a NoteInfo instance. This class helps create a note and
-         * return its values in a ContentValues map expected by data model methods.
-         * The note's id is created automatically when it is inserted into the data model.
-         */
-        public NoteInfo(String t, String n) {
-            title = t;
-            note = n;
-            createDate = 0;
-            modDate = 0;
-        }
-
-        // Sets the creation date for a test note
-        public void setCreationDate(long c) {
-            createDate = c;
-        }
-
-        // Sets the modification date for a test note
-        public void setModificationDate(long m) {
-            modDate = m;
-        }
-
-        /*
-         * Returns a ContentValues instance (a map) for this NoteInfo instance. This is useful for
-         * inserting a NoteInfo into a database.
-         */
-        public ContentValues getContentValues() {
-            // Gets a new ContentValues object
-            ContentValues v = new ContentValues();
-
-            // Adds map entries for the user-controlled fields in the map
-            v.put(NotePad.Notes.COLUMN_NAME_TITLE, title);
-            v.put(NotePad.Notes.COLUMN_NAME_NOTE, note);
-            v.put(NotePad.Notes.COLUMN_NAME_CREATE_DATE, createDate);
-            v.put(NotePad.Notes.COLUMN_NAME_MODIFICATION_DATE, modDate);
-            return v;
-
-        }
-    }
-}
diff --git a/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
similarity index 70%
rename from samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
rename to samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
index c29da44..80f71d2 100644
--- a/samples/NotePad/tests/src/com/example/android/notepad/NotePadActivityTest.java
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
@@ -19,22 +19,18 @@
 import android.test.ActivityInstrumentationTestCase2;
 
 import com.example.android.notepad.NotesList;
+
 /**
  * Make sure that the main launcher activity opens up properly, which will be
  * verified by {@link #testActivityTestCaseSetUpProperly}.
- *
- * To learn how to run an entire test package or one of its classes, please see
- * "Testing in Eclipse, with ADT" or "Testing in Other IDEs" in the Developer Guide.
  */
-public class NotePadActivityTest extends ActivityInstrumentationTestCase2<NotesList> {
+public class NotePadTest extends ActivityInstrumentationTestCase2<NotesList> {
 
     /**
      * Creates an {@link ActivityInstrumentationTestCase2} for the {@link NotesList} activity.
      */
-    public NotePadActivityTest() {
-        // This constructor was deprecated in API level 8 (SDK 2.2) but is
-        // used here so that the package remains compatible with API level 3 (SDK 1.5)
-        super("com.example.android.notepad", NotesList.class);
+    public NotePadTest() {
+        super(NotesList.class);
     }
 
     /**
