auto import from //depot/cupcake/@135843
diff --git a/samples/NotePad/Android.mk b/samples/NotePad/Android.mk
new file mode 100644
index 0000000..7939212
--- /dev/null
+++ b/samples/NotePad/Android.mk
@@ -0,0 +1,16 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_MODULE_TAGS := samples
+
+# Only compile source java files in this apk.
+LOCAL_SRC_FILES := $(call all-java-files-under, src)
+
+LOCAL_PACKAGE_NAME := NotePad
+
+LOCAL_SDK_VERSION := current
+
+include $(BUILD_PACKAGE)
+
+# Use the following include to make our test apk.
+include $(call all-makefiles-under,$(LOCAL_PATH))
diff --git a/samples/NotePad/AndroidManifest.xml b/samples/NotePad/AndroidManifest.xml
new file mode 100644
index 0000000..5c56daf
--- /dev/null
+++ b/samples/NotePad/AndroidManifest.xml
@@ -0,0 +1,104 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<!-- 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"
+        />
+
+        <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>
+            <intent-filter>
+                <action android:name="android.intent.action.VIEW" />
+                <action android:name="android.intent.action.EDIT" />
+                <action android:name="android.intent.action.PICK" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
+            </intent-filter>
+            <intent-filter>
+                <action android:name="android.intent.action.GET_CONTENT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
+            </intent-filter>
+        </activity>
+        
+        <activity android:name="NoteEditor"
+            android:theme="@android:style/Theme.Light"
+            android:label="@string/title_note"
+            android:screenOrientation="sensor"
+            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" />
+                <action android:name="com.android.notepad.action.EDIT_NOTE" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.item/vnd.google.note" />
+            </intent-filter>
+
+            <!-- This filter says that we can create a new note inside
+                 of a directory of notes. -->
+            <intent-filter>
+                <action android:name="android.intent.action.INSERT" />
+                <category android:name="android.intent.category.DEFAULT" />
+                <data android:mimeType="vnd.android.cursor.dir/vnd.google.note" />
+            </intent-filter>
+
+        </activity>
+        
+		<activity android:name="TitleEditor" android:label="@string/title_edit_title"
+				android:theme="@android:style/Theme.Dialog"
+                android:windowSoftInputMode="stateVisible">
+            <!-- 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>
+        
+    </application>
+</manifest>
+
diff --git a/samples/NotePad/_index.html b/samples/NotePad/_index.html
new file mode 100644
index 0000000..2a18969
--- /dev/null
+++ b/samples/NotePad/_index.html
@@ -0,0 +1,12 @@
+<p>A simple note pad application.
+It demonstrates...
+<ul> 
+<li>using views
+<li>accessing a database
+<li>using an intent to open a new window
+<li>managing activity lifecycle
+<li>and many other goodies...
+</ul>
+</p>
+<img alt="Note Pad Example" class="gallery"  src="sample_notepad.png" >
+<img alt="Note Pad Example" class="gallery"  src="sample_note.png"  >
diff --git a/samples/NotePad/res/drawable/app_notes.png b/samples/NotePad/res/drawable/app_notes.png
new file mode 100644
index 0000000..0479138
--- /dev/null
+++ b/samples/NotePad/res/drawable/app_notes.png
Binary files differ
diff --git a/samples/NotePad/res/layout/note_editor.xml b/samples/NotePad/res/layout/note_editor.xml
new file mode 100644
index 0000000..c54a963
--- /dev/null
+++ b/samples/NotePad/res/layout/note_editor.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<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:background="@android:color/transparent"
+    android:padding="5dip"
+    android:scrollbars="vertical"
+    android:fadingEdge="vertical"
+    android:gravity="top"
+    android:textSize="22sp"
+    android:capitalize="sentences"
+/>
diff --git a/samples/NotePad/res/layout/noteslist_item.xml b/samples/NotePad/res/layout/noteslist_item.xml
new file mode 100644
index 0000000..b167734
--- /dev/null
+++ b/samples/NotePad/res/layout/noteslist_item.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2006 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<TextView xmlns:android="http://schemas.android.com/apk/res/android"
+    android:id="@android:id/text1"
+    android:layout_width="fill_parent"
+    android:layout_height="?android:attr/listPreferredItemHeight"
+    android:textAppearance="?android:attr/textAppearanceLarge"
+    android:gravity="center_vertical"
+    android:paddingLeft="5dip"
+    android:singleLine="true"
+/>
diff --git a/samples/NotePad/res/layout/title_editor.xml b/samples/NotePad/res/layout/title_editor.xml
new file mode 100644
index 0000000..3593ec6
--- /dev/null
+++ b/samples/NotePad/res/layout/title_editor.xml
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 
+  	android:layout_width="wrap_content" 
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:paddingLeft="6dip"
+    android:paddingRight="6dip"
+    android:paddingBottom="3dip">
+   					  
+    <EditText android:id="@+id/title" 
+        android:maxLines="1" 
+        android:layout_marginTop="2dip"
+        android:layout_width="wrap_content"
+      	android:ems="25"
+        android:layout_height="wrap_content" 
+        android:autoText="true"
+        android:capitalize="sentences"
+        android:scrollHorizontally="true" />
+   		
+    <Button android:id="@+id/ok"
+        android:layout_width="wrap_content" 
+        android:layout_height="wrap_content" 
+        android:layout_gravity="right"
+        android:text="@string/button_ok" />
+   		
+</LinearLayout>
diff --git a/samples/NotePad/res/values/strings.xml b/samples/NotePad/res/values/strings.xml
new file mode 100644
index 0000000..b4bf671
--- /dev/null
+++ b/samples/NotePad/res/values/strings.xml
@@ -0,0 +1,38 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+
+<resources>
+    <string name="menu_delete">Delete</string>
+    <string name="menu_insert">Add note</string>
+    <string name="menu_revert">Revert</string>
+    <string name="menu_discard">Discard</string>
+
+    <string name="resolve_edit">Edit note</string>
+    <string name="resolve_title">Edit title</string>  
+
+    <string name="title_create">Create note</string>
+    <string name="title_edit">Edit note</string>
+	<string name="title_notes_list">Note pad</string>   
+	<string name="title_note">Note</string>  
+	<string name="title_edit_title">Note title:</string>  
+	
+	<string name="app_name">Note Pad</string>  
+	
+	<string name="button_ok">OK</string>  
+	
+	<string name="error_title">Error</string>
+	<string name="error_message">Error loading note</string>
+</resources>
diff --git a/samples/NotePad/sample_note.png b/samples/NotePad/sample_note.png
new file mode 100644
index 0000000..cea1a08
--- /dev/null
+++ b/samples/NotePad/sample_note.png
Binary files differ
diff --git a/samples/NotePad/sample_notepad.png b/samples/NotePad/sample_notepad.png
new file mode 100644
index 0000000..c498847
--- /dev/null
+++ b/samples/NotePad/sample_notepad.png
Binary files differ
diff --git a/samples/NotePad/src/com/example/android/notepad/NoteEditor.java b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
new file mode 100644
index 0000000..e45efd8
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NoteEditor.java
@@ -0,0 +1,347 @@
+/*
+ * 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.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.ContentValues;
+import android.content.Context;
+import android.content.Intent;
+import android.database.Cursor;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.Rect;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.widget.EditText;
+
+/**
+ * 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 note {@link Intent#ACTION_INSERT}.  
+ */
+public class NoteEditor extends Activity {
+    private static final String TAG = "Notes";
+
+    /**
+     * Standard projection for the interesting columns of a normal note.
+     */
+    private static final String[] PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.NOTE, // 1
+    };
+    /** The index of the note column */
+    private static final int COLUMN_INDEX_NOTE = 1;
+    
+    // This is our state data that is stored when freezing.
+    private static final String ORIGINAL_CONTENT = "origContent";
+
+    // Identifiers for our menu items.
+    private static final int REVERT_ID = Menu.FIRST;
+    private static final int DISCARD_ID = Menu.FIRST + 1;
+    private static final int DELETE_ID = Menu.FIRST + 2;
+
+    // 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 int mState;
+    private boolean mNoteOnly = false;
+    private Uri mUri;
+    private Cursor mCursor;
+    private EditText mText;
+    private String mOriginalContent;
+
+    /**
+     * 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;
+
+        // we need this constructor for LayoutInflater
+        public LinedEditText(Context context, AttributeSet attrs) {
+            super(context, attrs);
+            
+            mRect = new Rect();
+            mPaint = new Paint();
+            mPaint.setStyle(Paint.Style.STROKE);
+            mPaint.setColor(0x800000FF);
+        }
+        
+        @Override
+        protected void onDraw(Canvas canvas) {
+            int count = getLineCount();
+            Rect r = mRect;
+            Paint paint = mPaint;
+
+            for (int i = 0; i < count; i++) {
+                int baseline = getLineBounds(i, r);
+
+                canvas.drawLine(r.left, baseline + 1, r.right, baseline + 1, paint);
+            }
+
+            super.onDraw(canvas);
+        }
+    }
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        final Intent intent = getIntent();
+
+        // Do some setup based on the action being performed.
+
+        final String action = intent.getAction();
+        if (Intent.ACTION_EDIT.equals(action)) {
+            // Requested to edit: set that state, and the data being edited.
+            mState = STATE_EDIT;
+            mUri = intent.getData();
+        } else if (Intent.ACTION_INSERT.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 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) {
+                Log.e(TAG, "Failed to insert new note into " + getIntent().getData());
+                finish();
+                return;
+            }
+
+            // The new entry was created, so assume all will end well and
+            // set the result to be returned.
+            setResult(RESULT_OK, (new Intent()).setAction(mUri.toString()));
+
+        } else {
+            // Whoops, unknown action!  Bail.
+            Log.e(TAG, "Unknown action, exiting");
+            finish();
+            return;
+        }
+
+        // Set the layout for this activity.  You can find it in res/layout/note_editor.xml
+        setContentView(R.layout.note_editor);
+        
+        // The text view for our note, identified by its ID in the XML file.
+        mText = (EditText) findViewById(R.id.note);
+
+        // Get the note!
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
+
+        // 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);
+        }
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // If we didn't have any trouble retrieving the data, it is now
+        // time to get at the stuff.
+        if (mCursor != null) {
+            // Make sure we are at the one and only row in the cursor.
+            mCursor.moveToFirst();
+
+            // Modify our overall title depending on the mode we are running in.
+            if (mState == STATE_EDIT) {
+                setTitle(getText(R.string.title_edit));
+            } else if (mState == STATE_INSERT) {
+                setTitle(getText(R.string.title_create));
+            }
+
+            // 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);
+            
+            // 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;
+            }
+
+        } else {
+            setTitle(getText(R.string.error_title));
+            mText.setText(getText(R.string.error_message));
+        }
+    }
+
+    @Override
+    protected void onSaveInstanceState(Bundle outState) {
+        // Save away the original text, so we still have it if the activity
+        // needs to be killed while paused.
+        outState.putString(ORIGINAL_CONTENT, mOriginalContent);
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        // 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) {
+            String text = mText.getText().toString();
+            int length = text.length();
+
+            // 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();
+
+            // Get out updates into the provider.
+            } else {
+                ContentValues values = new ContentValues();
+
+                // This stuff is only done when working with a full-fledged note.
+                if (!mNoteOnly) {
+                    // Bump the modification time to now.
+                    values.put(Notes.MODIFIED_DATE, System.currentTimeMillis());
+
+                    // If we are creating a new note, then we want to also create
+                    // an initial title for it.
+                    if (mState == STATE_INSERT) {
+                        String 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);
+                    }
+                }
+
+                // Write our text back into the provider.
+                values.put(Notes.NOTE, text);
+
+                // 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);
+            }
+        }
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        // Build the menus that are shown when editing.
+        if (mState == STATE_EDIT) {
+            menu.add(0, REVERT_ID, 0, R.string.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);
+            }
+
+        // Build the menus that are shown when inserting.
+        } else {
+            menu.add(0, DISCARD_ID, 0, R.string.menu_discard)
+                    .setShortcut('0', 'd')
+                    .setIcon(android.R.drawable.ic_menu_delete);
+        }
+
+        // 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);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        // Handle all of the possible menu actions.
+        switch (item.getItemId()) {
+        case DELETE_ID:
+            deleteNote();
+            finish();
+            break;
+        case DISCARD_ID:
+            cancelNote();
+            break;
+        case REVERT_ID:
+            cancelNote();
+            break;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    /**
+     * 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();
+    }
+
+    /**
+     * Take care of deleting a note.  Simply deletes the entry.
+     */
+    private final void deleteNote() {
+        if (mCursor != null) {
+            mCursor.close();
+            mCursor = null;
+            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
new file mode 100644
index 0000000..25be23e
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotePad.java
@@ -0,0 +1,82 @@
+/*
+ * 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.example.android.notepad;
+
+import android.net.Uri;
+import android.provider.BaseColumns;
+
+/**
+ * Convenience definitions for NotePadProvider
+ */
+public final class NotePad {
+    public static final String AUTHORITY = "com.google.provider.NotePad";
+
+    // This class cannot be instantiated
+    private NotePad() {}
+    
+    /**
+     * Notes table
+     */
+    public static final class Notes implements BaseColumns {
+        // This class cannot be instantiated
+        private Notes() {}
+
+        /**
+         * The content:// style URL for this table
+         */
+        public static final Uri CONTENT_URI = Uri.parse("content://" + AUTHORITY + "/notes");
+
+        /**
+         * The MIME type of {@link #CONTENT_URI} providing a directory of notes.
+         */
+        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.
+         */
+        public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.google.note";
+
+        /**
+         * 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 from System.curentTimeMillis())</P>
+         */
+        public static final String CREATED_DATE = "created";
+
+        /**
+         * The timestamp for when the note was last modified
+         * <P>Type: INTEGER (long from System.curentTimeMillis())</P>
+         */
+        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
new file mode 100644
index 0000000..f1d3fdc
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotePadProvider.java
@@ -0,0 +1,249 @@
+/*
+ * 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.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.res.Resources;
+import android.database.Cursor;
+import android.database.SQLException;
+import android.database.sqlite.SQLiteDatabase;
+import android.database.sqlite.SQLiteOpenHelper;
+import android.database.sqlite.SQLiteQueryBuilder;
+import android.net.Uri;
+import android.text.TextUtils;
+import android.util.Log;
+
+import java.util.HashMap;
+
+/**
+ * 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 {
+
+    private static final String TAG = "NotePadProvider";
+
+    private static final String DATABASE_NAME = "note_pad.db";
+    private static final int DATABASE_VERSION = 2;
+    private static final String NOTES_TABLE_NAME = "notes";
+
+    private static HashMap<String, String> sNotesProjectionMap;
+
+    private static final int NOTES = 1;
+    private static final int NOTE_ID = 2;
+
+    private static final UriMatcher sUriMatcher;
+
+    /**
+     * This class helps open, create, and upgrade the database file.
+     */
+    private static class DatabaseHelper extends SQLiteOpenHelper {
+
+        DatabaseHelper(Context context) {
+            super(context, DATABASE_NAME, null, DATABASE_VERSION);
+        }
+
+        @Override
+        public void onCreate(SQLiteDatabase db) {
+            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"
+                    + ");");
+        }
+
+        @Override
+        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
+            Log.w(TAG, "Upgrading database from version " + oldVersion + " to "
+                    + newVersion + ", which will destroy all old data");
+            db.execSQL("DROP TABLE IF EXISTS notes");
+            onCreate(db);
+        }
+    }
+
+    private DatabaseHelper mOpenHelper;
+
+    @Override
+    public boolean onCreate() {
+        mOpenHelper = new DatabaseHelper(getContext());
+        return true;
+    }
+
+    @Override
+    public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
+            String sortOrder) {
+        SQLiteQueryBuilder qb = new SQLiteQueryBuilder();
+
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            qb.setTables(NOTES_TABLE_NAME);
+            qb.setProjectionMap(sNotesProjectionMap);
+            break;
+
+        case NOTE_ID:
+            qb.setTables(NOTES_TABLE_NAME);
+            qb.setProjectionMap(sNotesProjectionMap);
+            qb.appendWhere(Notes._ID + "=" + uri.getPathSegments().get(1));
+            break;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        // If no sort order is specified use the default
+        String orderBy;
+        if (TextUtils.isEmpty(sortOrder)) {
+            orderBy = NotePad.Notes.DEFAULT_SORT_ORDER;
+        } else {
+            orderBy = sortOrder;
+        }
+
+        // Get the database and run the query
+        SQLiteDatabase db = mOpenHelper.getReadableDatabase();
+        Cursor c = qb.query(db, projection, selection, selectionArgs, null, null, orderBy);
+
+        // Tell the cursor what uri to watch, so it knows when its source data changes
+        c.setNotificationUri(getContext().getContentResolver(), uri);
+        return c;
+    }
+
+    @Override
+    public String getType(Uri uri) {
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            return Notes.CONTENT_TYPE;
+
+        case NOTE_ID:
+            return Notes.CONTENT_ITEM_TYPE;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+    }
+
+    @Override
+    public Uri insert(Uri uri, ContentValues initialValues) {
+        // Validate the requested uri
+        if (sUriMatcher.match(uri) != NOTES) {
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        ContentValues values;
+        if (initialValues != null) {
+            values = new ContentValues(initialValues);
+        } else {
+            values = new ContentValues();
+        }
+
+        Long now = Long.valueOf(System.currentTimeMillis());
+
+        // Make sure that the fields are all set
+        if (values.containsKey(NotePad.Notes.CREATED_DATE) == false) {
+            values.put(NotePad.Notes.CREATED_DATE, now);
+        }
+
+        if (values.containsKey(NotePad.Notes.MODIFIED_DATE) == false) {
+            values.put(NotePad.Notes.MODIFIED_DATE, now);
+        }
+
+        if (values.containsKey(NotePad.Notes.TITLE) == false) {
+            Resources r = Resources.getSystem();
+            values.put(NotePad.Notes.TITLE, r.getString(android.R.string.untitled));
+        }
+
+        if (values.containsKey(NotePad.Notes.NOTE) == false) {
+            values.put(NotePad.Notes.NOTE, "");
+        }
+
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        long rowId = db.insert(NOTES_TABLE_NAME, Notes.NOTE, values);
+        if (rowId > 0) {
+            Uri noteUri = ContentUris.withAppendedId(NotePad.Notes.CONTENT_URI, rowId);
+            getContext().getContentResolver().notifyChange(noteUri, null);
+            return noteUri;
+        }
+
+        throw new SQLException("Failed to insert row into " + uri);
+    }
+
+    @Override
+    public int delete(Uri uri, String where, String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count;
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.delete(NOTES_TABLE_NAME, where, whereArgs);
+            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;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    @Override
+    public int update(Uri uri, ContentValues values, String where, String[] whereArgs) {
+        SQLiteDatabase db = mOpenHelper.getWritableDatabase();
+        int count;
+        switch (sUriMatcher.match(uri)) {
+        case NOTES:
+            count = db.update(NOTES_TABLE_NAME, values, where, whereArgs);
+            break;
+
+        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;
+
+        default:
+            throw new IllegalArgumentException("Unknown URI " + uri);
+        }
+
+        getContext().getContentResolver().notifyChange(uri, null);
+        return count;
+    }
+
+    static {
+        sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes", NOTES);
+        sUriMatcher.addURI(NotePad.AUTHORITY, "notes/#", NOTE_ID);
+
+        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);
+    }
+}
diff --git a/samples/NotePad/src/com/example/android/notepad/NotesList.java b/samples/NotePad/src/com/example/android/notepad/NotesList.java
new file mode 100644
index 0000000..ceaaa3c
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/NotesList.java
@@ -0,0 +1,215 @@
+/*
+ * 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.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.ListActivity;
+import android.content.ComponentName;
+import android.content.ContentUris;
+import android.content.Intent;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.util.Log;
+import android.view.ContextMenu;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.ContextMenu.ContextMenuInfo;
+import android.widget.AdapterView;
+import android.widget.ListView;
+import android.widget.SimpleCursorAdapter;
+
+/**
+ * Displays a list of notes. Will display notes from the {@link Uri}
+ * provided in the intent if there is one, otherwise defaults to displaying the
+ * contents of the {@link NotePadProvider}
+ */
+public class NotesList extends ListActivity {
+    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;
+
+    /**
+     * The columns we are interested in from the database
+     */
+    private static final String[] PROJECTION = new String[] {
+            Notes._ID, // 0
+            Notes.TITLE, // 1
+    };
+
+    /** The index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 1;
+    
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT);
+
+        // 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 (intent.getData() == null) {
+            intent.setData(Notes.CONTENT_URI);
+        }
+
+        // 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);
+
+        // 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);
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+        super.onCreateOptionsMenu(menu);
+
+        // 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);
+
+        // 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.
+        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);
+
+        return true;
+    }
+
+    @Override
+    public boolean onPrepareOptionsMenu(Menu menu) {
+        super.onPrepareOptionsMenu(menu);
+        final boolean haveItems = getListAdapter().getCount() > 0;
+
+        // 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) {
+            // This is the selected item.
+            Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId());
+
+            // Build menu...  always starts with the EDIT action...
+            Intent[] specifics = new Intent[1];
+            specifics[0] = new Intent(Intent.ACTION_EDIT, uri);
+            MenuItem[] items = new MenuItem[1];
+
+            // ... is followed by whatever other actions are available...
+            Intent intent = new Intent(null, uri);
+            intent.addCategory(Intent.CATEGORY_ALTERNATIVE);
+            menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0,
+                    items);
+
+            // Give a shortcut to the edit action.
+            if (items[0] != null) {
+                items[0].setShortcut('1', 'e');
+            }
+        } else {
+            menu.removeGroup(Menu.CATEGORY_ALTERNATIVE);
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+        switch (item.getItemId()) {
+        case MENU_ITEM_INSERT:
+            // Launch activity to insert a new item
+            startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData()));
+            return true;
+        }
+        return super.onOptionsItemSelected(item);
+    }
+
+    @Override
+    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) menuInfo;
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return;
+        }
+
+        Cursor cursor = (Cursor) getListAdapter().getItem(info.position);
+        if (cursor == null) {
+            // For some reason the requested item isn't available, do nothing
+            return;
+        }
+
+        // Setup the menu header
+        menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE));
+
+        // Add a menu item to delete the note
+        menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete);
+    }
+        
+    @Override
+    public boolean onContextItemSelected(MenuItem item) {
+        AdapterView.AdapterContextMenuInfo info;
+        try {
+             info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo();
+        } catch (ClassCastException e) {
+            Log.e(TAG, "bad menuInfo", e);
+            return false;
+        }
+
+        switch (item.getItemId()) {
+            case MENU_ITEM_DELETE: {
+                // Delete the note that the context menu is for
+                Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id);
+                getContentResolver().delete(noteUri, null, null);
+                return true;
+            }
+        }
+        return false;
+    }
+
+    @Override
+    protected void onListItemClick(ListView l, View v, int position, long id) {
+        Uri uri = ContentUris.withAppendedId(getIntent().getData(), id);
+        
+        String action = getIntent().getAction();
+        if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) {
+            // 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 {
+            // 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/TitleEditor.java b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
new file mode 100644
index 0000000..50d38e5
--- /dev/null
+++ b/samples/NotePad/src/com/example/android/notepad/TitleEditor.java
@@ -0,0 +1,115 @@
+/*
+ * 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.example.android.notepad;
+
+import com.example.android.notepad.NotePad.Notes;
+
+import android.app.Activity;
+import android.content.ContentValues;
+import android.database.Cursor;
+import android.net.Uri;
+import android.os.Bundle;
+import android.view.View;
+import android.widget.Button;
+import android.widget.EditText;
+
+/**
+ * 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".
+     */
+    public static final String EDIT_TITLE_ACTION = "com.android.notepad.action.EDIT_TITLE";
+
+    /**
+     * An array of the columns we are interested in.
+     */
+    private static final String[] PROJECTION = new String[] {
+            NotePad.Notes._ID, // 0
+            NotePad.Notes.TITLE, // 1
+    };
+    /** Index of the title column */
+    private static final int COLUMN_INDEX_TITLE = 1;
+
+    /**
+     * Cursor which will provide access to the note whose title we are editing.
+     */
+    private Cursor mCursor;
+
+    /**
+     * The EditText field from our UI. Keep track of this so we can extract the
+     * text when we are finished.
+     */
+    private EditText mText;
+
+    /**
+     * The content URI to the note that's being edited.
+     */
+    private Uri mUri;
+
+    @Override
+    public void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+
+        setContentView(R.layout.title_editor);
+
+        // Get the uri of the note whose title we want to edit
+        mUri = getIntent().getData();
+
+        // Get a cursor to access the note
+        mCursor = managedQuery(mUri, PROJECTION, null, null, null);
+
+        // Set up click handlers for the text field and button
+        mText = (EditText) this.findViewById(R.id.title);
+        mText.setOnClickListener(this);
+        
+        Button b = (Button) findViewById(R.id.ok);
+        b.setOnClickListener(this);
+    }
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+
+        // Initialize the text with the title column from the cursor
+        if (mCursor != null) {
+            mCursor.moveToFirst();
+            mText.setText(mCursor.getString(COLUMN_INDEX_TITLE));
+        }
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+
+        if (mCursor != null) {
+            // Write the title back to the note 
+            ContentValues values = new ContentValues();
+            values.put(Notes.TITLE, mText.getText().toString());
+            getContentResolver().update(mUri, values, null, null);
+        }
+    }
+
+    public void onClick(View v) {
+        // 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
new file mode 100644
index 0000000..43efafc
--- /dev/null
+++ b/samples/NotePad/tests/Android.mk
@@ -0,0 +1,14 @@
+LOCAL_PATH:= $(call my-dir)
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES := $(call all-subdir-java-files)
+
+LOCAL_JAVA_LIBRARIES := android.test.runner
+
+LOCAL_PACKAGE_NAME := NotePadTests
+
+LOCAL_MODULE_TAGS := tests
+
+LOCAL_INSTRUMENTATION_FOR := NotePad
+
+include $(BUILD_PACKAGE)
diff --git a/samples/NotePad/tests/AndroidManifest.xml b/samples/NotePad/tests/AndroidManifest.xml
new file mode 100644
index 0000000..afd502b
--- /dev/null
+++ b/samples/NotePad/tests/AndroidManifest.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2008 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+  
+          http://www.apache.org/licenses/LICENSE-2.0
+  
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+
+<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>
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+  <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/src/com/example/android/notepad/NotePadTest.java b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
new file mode 100644
index 0000000..452c599
--- /dev/null
+++ b/samples/NotePad/tests/src/com/example/android/notepad/NotePadTest.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2008 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.example.android.notepad;
+
+import android.test.ActivityInstrumentationTestCase;
+
+import com.example.android.notepad.NotesList;
+
+/**
+ * Make sure that the main launcher activity opens up properly, which will be
+ * verified by {@link ActivityTestCase#testActivityTestCaseSetUpProperly}.
+ */
+public class NotePadTest extends ActivityInstrumentationTestCase<NotesList> {
+
+  public NotePadTest() {
+      super("com.example.android.notepad", NotesList.class);
+  }
+
+}