Merge change I95a34d28 into eclair

* changes:
  ADT XML String Refactoring: fix refusing to edit @+id/blah.
diff --git a/apps/CustomLocale/res/drawable-hdpi/icon.png b/apps/CustomLocale/res/drawable-hdpi/icon.png
new file mode 100755
index 0000000..60fbdf5
--- /dev/null
+++ b/apps/CustomLocale/res/drawable-hdpi/icon.png
Binary files differ
diff --git a/apps/CustomLocale/res/drawable/icon.png b/apps/CustomLocale/res/drawable-mdpi/icon.png
similarity index 100%
rename from apps/CustomLocale/res/drawable/icon.png
rename to apps/CustomLocale/res/drawable-mdpi/icon.png
Binary files differ
diff --git a/apps/Development/res/drawable-hdpi/ic_launcher_devtools.png b/apps/Development/res/drawable-hdpi/ic_launcher_devtools.png
new file mode 100755
index 0000000..60fbdf5
--- /dev/null
+++ b/apps/Development/res/drawable-hdpi/ic_launcher_devtools.png
Binary files differ
diff --git a/apps/Development/res/drawable-hdpi/stat_sample.png b/apps/Development/res/drawable-hdpi/stat_sample.png
new file mode 100755
index 0000000..adb9dcb
--- /dev/null
+++ b/apps/Development/res/drawable-hdpi/stat_sample.png
Binary files differ
diff --git a/apps/Development/res/drawable/ic_launcher_devtools.png b/apps/Development/res/drawable-mdpi/ic_launcher_devtools.png
similarity index 100%
rename from apps/Development/res/drawable/ic_launcher_devtools.png
rename to apps/Development/res/drawable-mdpi/ic_launcher_devtools.png
Binary files differ
diff --git a/apps/Development/res/drawable/stat_sample.png b/apps/Development/res/drawable-mdpi/stat_sample.png
similarity index 100%
rename from apps/Development/res/drawable/stat_sample.png
rename to apps/Development/res/drawable-mdpi/stat_sample.png
Binary files differ
diff --git a/apps/GestureBuilder/res/drawable-hdpi/ic_gesturebuilder.png b/apps/GestureBuilder/res/drawable-hdpi/ic_gesturebuilder.png
new file mode 100755
index 0000000..595b9e1
--- /dev/null
+++ b/apps/GestureBuilder/res/drawable-hdpi/ic_gesturebuilder.png
Binary files differ
diff --git a/apps/GestureBuilder/res/drawable/ic_gesturebuilder.png b/apps/GestureBuilder/res/drawable-mdpi/ic_gesturebuilder.png
similarity index 100%
rename from apps/GestureBuilder/res/drawable/ic_gesturebuilder.png
rename to apps/GestureBuilder/res/drawable-mdpi/ic_gesturebuilder.png
Binary files differ
diff --git a/apps/SpareParts/res/drawable-hdpi/app_icon.png b/apps/SpareParts/res/drawable-hdpi/app_icon.png
new file mode 100755
index 0000000..60fbdf5
--- /dev/null
+++ b/apps/SpareParts/res/drawable-hdpi/app_icon.png
Binary files differ
diff --git a/apps/SpareParts/res/drawable/app_icon.png b/apps/SpareParts/res/drawable-mdpi/app_icon.png
similarity index 100%
rename from apps/SpareParts/res/drawable/app_icon.png
rename to apps/SpareParts/res/drawable-mdpi/app_icon.png
Binary files differ
diff --git a/apps/Term/res/drawable-hdpi/app_terminal.png b/apps/Term/res/drawable-hdpi/app_terminal.png
new file mode 100755
index 0000000..278b2a5
--- /dev/null
+++ b/apps/Term/res/drawable-hdpi/app_terminal.png
Binary files differ
diff --git a/apps/Term/res/drawable-hdpi/atari_small.png b/apps/Term/res/drawable-hdpi/atari_small.png
new file mode 100755
index 0000000..8bdd624
--- /dev/null
+++ b/apps/Term/res/drawable-hdpi/atari_small.png
Binary files differ
diff --git a/apps/Term/res/drawable/app_terminal.png b/apps/Term/res/drawable-mdpi/app_terminal.png
similarity index 100%
rename from apps/Term/res/drawable/app_terminal.png
rename to apps/Term/res/drawable-mdpi/app_terminal.png
Binary files differ
diff --git a/apps/Term/res/drawable/atari_small.png b/apps/Term/res/drawable-mdpi/atari_small.png
similarity index 100%
rename from apps/Term/res/drawable/atari_small.png
rename to apps/Term/res/drawable-mdpi/atari_small.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/alert_dialog_icon.png b/samples/ApiDemos/res/drawable-hdpi/alert_dialog_icon.png
new file mode 100755
index 0000000..fe54477
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/alert_dialog_icon.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/app_sample_code.png b/samples/ApiDemos/res/drawable-hdpi/app_sample_code.png
new file mode 100755
index 0000000..66a1984
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/app_sample_code.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/arrow_down_float.png b/samples/ApiDemos/res/drawable-hdpi/arrow_down_float.png
new file mode 100755
index 0000000..923d330
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/arrow_down_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/arrow_up_float.png b/samples/ApiDemos/res/drawable-hdpi/arrow_up_float.png
new file mode 100755
index 0000000..eda5faf
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/arrow_up_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/btn_check_off.png b/samples/ApiDemos/res/drawable-hdpi/btn_check_off.png
new file mode 100755
index 0000000..0cf1f04
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/btn_check_off.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/btn_check_on.png b/samples/ApiDemos/res/drawable-hdpi/btn_check_on.png
new file mode 100755
index 0000000..fc791c4
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/btn_check_on.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/btn_circle_normal.png b/samples/ApiDemos/res/drawable-hdpi/btn_circle_normal.png
new file mode 100755
index 0000000..bf3fb5a
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/btn_circle_normal.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/btn_default_normal.9.png b/samples/ApiDemos/res/drawable-hdpi/btn_default_normal.9.png
new file mode 100755
index 0000000..5d3d733
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/btn_default_normal.9.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/button.9.png b/samples/ApiDemos/res/drawable-hdpi/button.9.png
new file mode 100755
index 0000000..6995e60
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/button.9.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/ic_popup_reminder.png b/samples/ApiDemos/res/drawable-hdpi/ic_popup_reminder.png
new file mode 100755
index 0000000..9652dde
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/ic_popup_reminder.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/icon48x48_2.png b/samples/ApiDemos/res/drawable-hdpi/icon48x48_2.png
new file mode 100755
index 0000000..1e256e6
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/icon48x48_2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/progress_circular_background.png b/samples/ApiDemos/res/drawable-hdpi/progress_circular_background.png
new file mode 100755
index 0000000..c4ecd1f
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/progress_circular_background.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/progress_particle.png b/samples/ApiDemos/res/drawable-hdpi/progress_particle.png
new file mode 100755
index 0000000..3e72fb4
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/progress_particle.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/robot.png b/samples/ApiDemos/res/drawable-hdpi/robot.png
new file mode 100755
index 0000000..3e4fd21
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/robot.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/scrollbar_state2.png b/samples/ApiDemos/res/drawable-hdpi/scrollbar_state2.png
new file mode 100755
index 0000000..41ed5b7
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/scrollbar_state2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/star_big_on.png b/samples/ApiDemos/res/drawable-hdpi/star_big_on.png
new file mode 100755
index 0000000..944918e
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/star_big_on.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/stat_happy.png b/samples/ApiDemos/res/drawable-hdpi/stat_happy.png
new file mode 100755
index 0000000..27f5bb7
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/stat_happy.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/stat_neutral.png b/samples/ApiDemos/res/drawable-hdpi/stat_neutral.png
new file mode 100755
index 0000000..34073ff
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/stat_neutral.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/stat_sad.png b/samples/ApiDemos/res/drawable-hdpi/stat_sad.png
new file mode 100755
index 0000000..25004cd
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/stat_sad.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable-hdpi/stat_sample.png b/samples/ApiDemos/res/drawable-hdpi/stat_sample.png
new file mode 100755
index 0000000..6c9ba0a
--- /dev/null
+++ b/samples/ApiDemos/res/drawable-hdpi/stat_sample.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/alert_dialog_icon.png b/samples/ApiDemos/res/drawable-mdpi/alert_dialog_icon.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/alert_dialog_icon.png
rename to samples/ApiDemos/res/drawable-mdpi/alert_dialog_icon.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/app_sample_code.png b/samples/ApiDemos/res/drawable-mdpi/app_sample_code.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/app_sample_code.png
rename to samples/ApiDemos/res/drawable-mdpi/app_sample_code.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/arrow_down_float.png b/samples/ApiDemos/res/drawable-mdpi/arrow_down_float.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/arrow_down_float.png
rename to samples/ApiDemos/res/drawable-mdpi/arrow_down_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/arrow_up_float.png b/samples/ApiDemos/res/drawable-mdpi/arrow_up_float.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/arrow_up_float.png
rename to samples/ApiDemos/res/drawable-mdpi/arrow_up_float.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/btn_check_off.png b/samples/ApiDemos/res/drawable-mdpi/btn_check_off.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/btn_check_off.png
rename to samples/ApiDemos/res/drawable-mdpi/btn_check_off.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/btn_check_on.png b/samples/ApiDemos/res/drawable-mdpi/btn_check_on.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/btn_check_on.png
rename to samples/ApiDemos/res/drawable-mdpi/btn_check_on.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/btn_circle_normal.png b/samples/ApiDemos/res/drawable-mdpi/btn_circle_normal.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/btn_circle_normal.png
rename to samples/ApiDemos/res/drawable-mdpi/btn_circle_normal.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/btn_default_normal.9.png b/samples/ApiDemos/res/drawable-mdpi/btn_default_normal.9.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/btn_default_normal.9.png
rename to samples/ApiDemos/res/drawable-mdpi/btn_default_normal.9.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/button.9.png b/samples/ApiDemos/res/drawable-mdpi/button.9.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/button.9.png
rename to samples/ApiDemos/res/drawable-mdpi/button.9.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/ic_popup_reminder.png b/samples/ApiDemos/res/drawable-mdpi/ic_popup_reminder.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/ic_popup_reminder.png
rename to samples/ApiDemos/res/drawable-mdpi/ic_popup_reminder.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/icon48x48_2.png b/samples/ApiDemos/res/drawable-mdpi/icon48x48_2.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/icon48x48_2.png
rename to samples/ApiDemos/res/drawable-mdpi/icon48x48_2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/progress_circular_background.png b/samples/ApiDemos/res/drawable-mdpi/progress_circular_background.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/progress_circular_background.png
rename to samples/ApiDemos/res/drawable-mdpi/progress_circular_background.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/progress_particle.png b/samples/ApiDemos/res/drawable-mdpi/progress_particle.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/progress_particle.png
rename to samples/ApiDemos/res/drawable-mdpi/progress_particle.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/robot.png b/samples/ApiDemos/res/drawable-mdpi/robot.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/robot.png
rename to samples/ApiDemos/res/drawable-mdpi/robot.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/scrollbar_state2.png b/samples/ApiDemos/res/drawable-mdpi/scrollbar_state2.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/scrollbar_state2.png
rename to samples/ApiDemos/res/drawable-mdpi/scrollbar_state2.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/star_big_on.png b/samples/ApiDemos/res/drawable-mdpi/star_big_on.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/star_big_on.png
rename to samples/ApiDemos/res/drawable-mdpi/star_big_on.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_happy.png b/samples/ApiDemos/res/drawable-mdpi/stat_happy.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/stat_happy.png
rename to samples/ApiDemos/res/drawable-mdpi/stat_happy.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_neutral.png b/samples/ApiDemos/res/drawable-mdpi/stat_neutral.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/stat_neutral.png
rename to samples/ApiDemos/res/drawable-mdpi/stat_neutral.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_sad.png b/samples/ApiDemos/res/drawable-mdpi/stat_sad.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/stat_sad.png
rename to samples/ApiDemos/res/drawable-mdpi/stat_sad.png
Binary files differ
diff --git a/samples/ApiDemos/res/drawable/stat_sample.png b/samples/ApiDemos/res/drawable-mdpi/stat_sample.png
similarity index 100%
rename from samples/ApiDemos/res/drawable/stat_sample.png
rename to samples/ApiDemos/res/drawable-mdpi/stat_sample.png
Binary files differ
diff --git a/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
new file mode 100755
index 0000000..4d9d559
--- /dev/null
+++ b/samples/BrowserPlugin/res/drawable-hdpi/sample_browser_plugin.png
Binary files differ
diff --git a/samples/BrowserPlugin/res/drawable/sample_browser_plugin.png b/samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
similarity index 100%
rename from samples/BrowserPlugin/res/drawable/sample_browser_plugin.png
rename to samples/BrowserPlugin/res/drawable-mdpi/sample_browser_plugin.png
Binary files differ
diff --git a/samples/FixedGridLayout/res/drawable-hdpi/bugdroid.png b/samples/FixedGridLayout/res/drawable-hdpi/bugdroid.png
new file mode 100755
index 0000000..e64968f
--- /dev/null
+++ b/samples/FixedGridLayout/res/drawable-hdpi/bugdroid.png
Binary files differ
diff --git a/samples/FixedGridLayout/res/drawable/bugdroid.png b/samples/FixedGridLayout/res/drawable-mdpi/bugdroid.png
similarity index 100%
rename from samples/FixedGridLayout/res/drawable/bugdroid.png
rename to samples/FixedGridLayout/res/drawable-mdpi/bugdroid.png
Binary files differ
diff --git a/samples/GlobalTime/res/drawable-hdpi/app_global_time.png b/samples/GlobalTime/res/drawable-hdpi/app_global_time.png
new file mode 100755
index 0000000..46c658e
--- /dev/null
+++ b/samples/GlobalTime/res/drawable-hdpi/app_global_time.png
Binary files differ
diff --git a/samples/GlobalTime/res/drawable/app_global_time.png b/samples/GlobalTime/res/drawable-mdpi/app_global_time.png
similarity index 100%
rename from samples/GlobalTime/res/drawable/app_global_time.png
rename to samples/GlobalTime/res/drawable-mdpi/app_global_time.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/all_applications_label_background.9.png b/samples/Home/res/drawable-hdpi/all_applications_label_background.9.png
new file mode 100755
index 0000000..75adf05
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/all_applications_label_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/application_background.9.png b/samples/Home/res/drawable-hdpi/application_background.9.png
new file mode 100755
index 0000000..70ae4d9
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/application_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/application_background_static.png b/samples/Home/res/drawable-hdpi/application_background_static.png
new file mode 100755
index 0000000..450eaa4
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/focused_application_background_static.png b/samples/Home/res/drawable-hdpi/focused_application_background_static.png
new file mode 100755
index 0000000..bec2cd9
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/focused_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/hide_all_applications.png b/samples/Home/res/drawable-hdpi/hide_all_applications.png
new file mode 100755
index 0000000..13e188f
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/hide_all_applications.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/ic_launcher_allhide.png b/samples/Home/res/drawable-hdpi/ic_launcher_allhide.png
new file mode 100755
index 0000000..9bef2ea
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/ic_launcher_allhide.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/ic_launcher_allshow.png b/samples/Home/res/drawable-hdpi/ic_launcher_allshow.png
new file mode 100755
index 0000000..2a6f86a
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/ic_launcher_allshow.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/ic_launcher_home.png b/samples/Home/res/drawable-hdpi/ic_launcher_home.png
new file mode 100755
index 0000000..1e256e6
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/ic_launcher_home.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/pressed_application_background_static.png b/samples/Home/res/drawable-hdpi/pressed_application_background_static.png
new file mode 100755
index 0000000..9931571
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/pressed_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable-hdpi/show_all_applications.png b/samples/Home/res/drawable-hdpi/show_all_applications.png
new file mode 100755
index 0000000..2a768b7
--- /dev/null
+++ b/samples/Home/res/drawable-hdpi/show_all_applications.png
Binary files differ
diff --git a/samples/Home/res/drawable/all_applications_label_background.9.png b/samples/Home/res/drawable-mdpi/all_applications_label_background.9.png
similarity index 100%
rename from samples/Home/res/drawable/all_applications_label_background.9.png
rename to samples/Home/res/drawable-mdpi/all_applications_label_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable/application_background.9.png b/samples/Home/res/drawable-mdpi/application_background.9.png
similarity index 100%
rename from samples/Home/res/drawable/application_background.9.png
rename to samples/Home/res/drawable-mdpi/application_background.9.png
Binary files differ
diff --git a/samples/Home/res/drawable/application_background_static.png b/samples/Home/res/drawable-mdpi/application_background_static.png
similarity index 100%
rename from samples/Home/res/drawable/application_background_static.png
rename to samples/Home/res/drawable-mdpi/application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/focused_application_background_static.png b/samples/Home/res/drawable-mdpi/focused_application_background_static.png
similarity index 100%
rename from samples/Home/res/drawable/focused_application_background_static.png
rename to samples/Home/res/drawable-mdpi/focused_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/hide_all_applications.png b/samples/Home/res/drawable-mdpi/hide_all_applications.png
similarity index 100%
rename from samples/Home/res/drawable/hide_all_applications.png
rename to samples/Home/res/drawable-mdpi/hide_all_applications.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_allhide.png b/samples/Home/res/drawable-mdpi/ic_launcher_allhide.png
similarity index 100%
rename from samples/Home/res/drawable/ic_launcher_allhide.png
rename to samples/Home/res/drawable-mdpi/ic_launcher_allhide.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_allshow.png b/samples/Home/res/drawable-mdpi/ic_launcher_allshow.png
similarity index 100%
rename from samples/Home/res/drawable/ic_launcher_allshow.png
rename to samples/Home/res/drawable-mdpi/ic_launcher_allshow.png
Binary files differ
diff --git a/samples/Home/res/drawable/ic_launcher_home.png b/samples/Home/res/drawable-mdpi/ic_launcher_home.png
similarity index 100%
rename from samples/Home/res/drawable/ic_launcher_home.png
rename to samples/Home/res/drawable-mdpi/ic_launcher_home.png
Binary files differ
diff --git a/samples/Home/res/drawable/pressed_application_background_static.png b/samples/Home/res/drawable-mdpi/pressed_application_background_static.png
similarity index 100%
rename from samples/Home/res/drawable/pressed_application_background_static.png
rename to samples/Home/res/drawable-mdpi/pressed_application_background_static.png
Binary files differ
diff --git a/samples/Home/res/drawable/show_all_applications.png b/samples/Home/res/drawable-mdpi/show_all_applications.png
similarity index 100%
rename from samples/Home/res/drawable/show_all_applications.png
rename to samples/Home/res/drawable-mdpi/show_all_applications.png
Binary files differ
diff --git a/samples/NotePad/res/drawable-hdpi/app_notes.png b/samples/NotePad/res/drawable-hdpi/app_notes.png
new file mode 100755
index 0000000..258d3d1
--- /dev/null
+++ b/samples/NotePad/res/drawable-hdpi/app_notes.png
Binary files differ
diff --git a/samples/NotePad/res/drawable/app_notes.png b/samples/NotePad/res/drawable-mdpi/app_notes.png
similarity index 100%
rename from samples/NotePad/res/drawable/app_notes.png
rename to samples/NotePad/res/drawable-mdpi/app_notes.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png
new file mode 100755
index 0000000..5139c71
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png
new file mode 100755
index 0000000..471c502
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_done.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png
new file mode 100755
index 0000000..5a5670c
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_return.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png
new file mode 100755
index 0000000..e72cde3
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_search.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png
new file mode 100755
index 0000000..2757696
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png
new file mode 100755
index 0000000..cef2daa
--- /dev/null
+++ b/samples/SoftKeyboard/res/drawable-hdpi/sym_keyboard_space.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_delete.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_delete.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_delete.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_delete.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_done.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_done.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_done.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_done.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_return.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_return.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_return.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_return.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_search.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_search.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_search.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_search.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_shift.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_shift.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_shift.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_shift.png
Binary files differ
diff --git a/samples/SoftKeyboard/res/drawable/sym_keyboard_space.png b/samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_space.png
similarity index 100%
rename from samples/SoftKeyboard/res/drawable/sym_keyboard_space.png
rename to samples/SoftKeyboard/res/drawable-mdpi/sym_keyboard_space.png
Binary files differ
diff --git a/testrunner/android_manifest.py b/testrunner/android_manifest.py
index 7ede96c..5406f56 100644
--- a/testrunner/android_manifest.py
+++ b/testrunner/android_manifest.py
@@ -22,6 +22,7 @@
 """
 
 # python imports
+import os
 import xml.dom.minidom
 import xml.parsers
 
@@ -29,7 +30,7 @@
 class AndroidManifest(object):
   """In memory representation of AndroidManifest.xml file."""
 
-  FILENAME = "AndroidManifest.xml"
+  FILENAME = 'AndroidManifest.xml'
 
   def __init__(self, app_path=None):
     if app_path:
@@ -41,10 +42,10 @@
     Returns:
       Package name if defined, otherwise None
     """
-    manifests = self._dom.getElementsByTagName("manifest")
-    if not manifests or not manifests[0].getAttribute("package"):
+    manifest = self._GetManifestElement()
+    if not manifest or not manifest.hasAttribute('package'):
       return None
-    return manifests[0].getAttribute("package")
+    return manifest.getAttribute('package')
 
   def ParseManifest(self, app_path):
     """Parse AndroidManifest.xml at the specified path.
@@ -55,6 +56,37 @@
       IOError: AndroidManifest.xml cannot be found at given path, or cannot be
           opened for reading
     """
-    self.app_path = app_path.rstrip("/")
-    self.manifest_path = "%s/%s" % (self.app_path, self.FILENAME)
-    self._dom = xml.dom.minidom.parse(self.manifest_path)
+    self._manifest_path = os.path.join(app_path, self.FILENAME)
+    self._dom = xml.dom.minidom.parse(self._manifest_path)
+
+  def AddUsesSdk(self, min_sdk_version):
+    """Adds a uses-sdk element to manifest.
+
+    Args:
+      min_sdk_version: value to provide for minSdkVersion attribute.
+    """
+    manifest = self._GetManifestElement()
+    uses_sdk_elements = manifest.getElementsByTagName('uses-sdk')
+    if uses_sdk_elements:
+      uses_sdk_element = uses_sdk_elements[0]
+    else:
+      uses_sdk_element = self._dom.createElement('uses-sdk')
+      manifest.appendChild(uses_sdk_element)
+
+    uses_sdk_element.setAttribute('android:minSdkVersion', min_sdk_version)
+    self._SaveXml()
+
+  def _GetManifestElement(self):
+    """Retrieve the root manifest element.
+
+    Returns:
+      the DOM element for manifest or None.
+    """
+    manifests = self._dom.getElementsByTagName('manifest')
+    if not manifests:
+      return None
+    return manifests[0]
+
+  def _SaveXml(self):
+    """Saves the manifest to disk."""
+    self._dom.writexml(open(self._manifest_path, mode='w'), encoding='utf-8')
diff --git a/testrunner/run_command.py b/testrunner/run_command.py
index c522e00..926cc6b 100755
--- a/testrunner/run_command.py
+++ b/testrunner/run_command.py
@@ -34,16 +34,25 @@
   global _abort_on_error
   _abort_on_error = abort
 
-def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True):
-  """Spawns a subprocess to run the given shell command, and checks for
-  timeout_time. If return_output is True, the output of the command is returned
-  as a string. Otherwise, output of command directed to stdout """
+def RunCommand(cmd, timeout_time=None, retry_count=3, return_output=True,
+               stdin_input=None):
+  """Spawn and retry a subprocess to run the given shell command.
 
+  Args:
+    cmd: shell command to run
+    timeout_time: time in seconds to wait for command to run before aborting.
+    retry_count: number of times to retry command
+    return_output: if True return output of command as string. Otherwise,
+      direct output of command to stdout.
+    stdin_input: data to feed to stdin
+  Returns:
+    output of command
+  """
   result = None
   while True:
     try:
       result = RunOnce(cmd, timeout_time=timeout_time,
-                       return_output=return_output)
+                       return_output=return_output, stdin_input=stdin_input)
     except errors.WaitForResponseTimedOutError:
       if retry_count == 0:
         raise
@@ -53,7 +62,22 @@
       # Success
       return result
 
-def RunOnce(cmd, timeout_time=None, return_output=True):
+def RunOnce(cmd, timeout_time=None, return_output=True, stdin_input=None):
+  """Spawns a subprocess to run the given shell command.
+
+  Args:
+    cmd: shell command to run
+    timeout_time: time in seconds to wait for command to run before aborting.
+    return_output: if True return output of command as string. Otherwise,
+      direct output of command to stdout.
+    stdin_input: data to feed to stdin
+  Returns:
+    output of command
+  Raises:
+    errors.WaitForResponseTimedOutError if command did not complete within
+      timeout_time seconds.
+    errors.AbortError is command returned error code and SetAbortOnError is on.
+  """
   start_time = time.time()
   so = []
   pid = []
@@ -67,15 +91,20 @@
     else:
       # None means direct to stdout
       output_dest = None
+    if stdin_input:
+      stdin_dest = subprocess.PIPE
+    else:
+      stdin_dest = None
     pipe = subprocess.Popen(
         cmd,
         executable='/bin/bash',
+        stdin=stdin_dest,
         stdout=output_dest,
         stderr=subprocess.STDOUT,
         shell=True)
     pid.append(pipe.pid)
     try:
-      output = pipe.communicate()[0]
+      output = pipe.communicate(input=stdin_input)[0]
       if output is not None and len(output) > 0:
         so.append(output)
     except OSError, e:
@@ -84,7 +113,7 @@
       so.append("ERROR")
       error_occurred = True
     if pipe.returncode != 0:
-      logger.SilentLog("Error: %s returned %s error code" %(cmd,
+      logger.SilentLog("Error: %s returned %d error code" %(cmd,
           pipe.returncode))
       error_occurred = True
 
diff --git a/testrunner/test_defs.xml b/testrunner/test_defs.xml
index 6d38d1d..7b75a68 100644
--- a/testrunner/test_defs.xml
+++ b/testrunner/test_defs.xml
@@ -366,14 +366,16 @@
 <test name="contactsprov"
     build_path="packages/providers/ContactsProvider/tests"
     package="com.android.providers.contacts.tests"
-    coverage_target="ContactsProvider" />
+    coverage_target="ContactsProvider"
+    continuous="true" />
 
 <test name="contacts"
     build_path="packages/apps/Contacts"
     package="com.android.contacts.tests"
     runner="android.test.InstrumentationTestRunner"
     coverage_target="Contacts"
-    description="Tests for the Contacts app." />
+    description="Tests for the Contacts app."
+    continuous="true" />
 
 <test name="gcontactsprov"
     build_path="packages/providers/GoogleContactsProvider/tests"
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java
index ae0bb5b..69bf18b 100755
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/LayoutConfigsXsd.java
@@ -94,8 +94,13 @@
 

     public static final String NODE_SCREEN_DIMENSION = "screen-dimension";          //$NON-NLS-1$

 

+    /** The screen-dimension element has 2 size element children. */

     public static final String NODE_SIZE = "size";                                  //$NON-NLS-1$

 

+    public static final String NODE_XPDI = "xdpi";                                  //$NON-NLS-1$

+

+    public static final String NODE_YDPI = "ydpi";                                  //$NON-NLS-1$

+

     /**

      * The "name" attribute, used by both the "device" and the "config"

      * elements. It represents the user-interface name of these objects.

diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd
index 476fce7..49131fb 100755
--- a/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.adt/src/com/android/ide/eclipse/adt/internal/sdk/layout-configs.xsd
@@ -24,7 +24,7 @@
 
     <xsd:element name="layout-configs">
         <xsd:annotation>
-            <xsd:documentation>
+            <xsd:documentation xml:lang="en">
                 The "layout-configs" element is the root element of this schema.
 
                 It must contain one or more "device" elements that each define the configurations
@@ -41,7 +41,7 @@
                 <xsd:element name="device" minOccurs="1" maxOccurs="unbounded">
 
                     <xsd:annotation>
-                        <xsd:documentation>
+                        <xsd:documentation xml:lang="en">
                             A device element must contain at most one "default" element
                             followed by one or more "config" elements.
 
@@ -78,10 +78,14 @@
     -->
     <xsd:complexType name="parametersType">
         <xsd:annotation>
-            <xsd:documentation>
+            <xsd:documentation xml:lang="en">
                 The parametersType define all the parameters that can happen either in a
                 "default" element or in a named "config" element.
                 Each parameter element can appear once at most.
+
+                Parameters here are the same as those used to specify alternate Android
+                resources, as documented by
+                http://d.android.com/guide/topics/resources/resources-i18n.html#AlternateResources
             </xsd:documentation>
         </xsd:annotation>
 
@@ -89,6 +93,11 @@
             <!-- parametersType says that 0..1 of each of these elements must be declared. -->
 
             <xsd:element name="screen-size" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies that the configuration is for a particular class of screen.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="small" />
@@ -99,6 +108,14 @@
             </xsd:element>
 
             <xsd:element name="screen-ratio" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies that the configuration is for a taller/wider than traditional
+                        screen. This is based purely on the aspect ration of the screen: QVGA,
+                        HVGA, and VGA are notlong; WQVGA, WVGA, FWVGA are long. Note that long
+                        may mean either wide or tall, depending on the current orientation.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="long" />
@@ -108,6 +125,12 @@
             </xsd:element>
 
             <xsd:element name="screen-orientation" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies that the configuration is for a screen that is tall (port) or
+                        wide (land).
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="port" />
@@ -118,6 +141,17 @@
             </xsd:element>
 
             <xsd:element name="pixel-density" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the screen density the configuration is defined for. The medium
+                        density of traditional HVGA screens (mdpi) is defined to be approximately
+                        160dpi; low density (ldpi) is 120, and high density (hdpi) is 240. There
+                        is thus a 4:3 scaling factor between each density, so a 9x9 bitmap in ldpi
+                        would be 12x12 is mdpi and 16x16 in hdpi.
+                        The special nodpi density that can be used in resource qualifiers is not
+                        a valid keyword here.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="ldpi" />
@@ -128,6 +162,11 @@
             </xsd:element>
 
             <xsd:element name="touch-type" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the touch type the configuration is defined for.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="notouch" />
@@ -138,6 +177,12 @@
             </xsd:element>
 
             <xsd:element name="keyboard-state" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        If your configuration uses a soft keyboard, use the keyssoft value.
+                        If it doesn't and has a real keyboard, use keysexposed or keyshidden.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="keysexposed" />
@@ -148,6 +193,11 @@
             </xsd:element>
 
             <xsd:element name="text-input-method" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the primary text input method the configuration is designed for.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="nokeys" />
@@ -158,6 +208,12 @@
             </xsd:element>
 
             <xsd:element name="nav-method" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the primary non-touchscreen navigation method the configuration
+                        is designed for.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:simpleType>
                     <xsd:restriction base="xsd:token">
                         <xsd:enumeration value="dpad" />
@@ -169,6 +225,11 @@
             </xsd:element>
 
             <xsd:element name="screen-dimension" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the device screen resolution, in pixels.
+                    </xsd:documentation>
+                </xsd:annotation>
                 <xsd:complexType>
                     <xsd:sequence minOccurs="2" maxOccurs="2">
 
@@ -181,6 +242,33 @@
                     </xsd:sequence>
                 </xsd:complexType>
             </xsd:element>
+
+            <xsd:element name="xdpi" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the actual density in X of the device screen.
+                    </xsd:documentation>
+                </xsd:annotation>
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:float">
+                        <xsd:minExclusive value="0" />
+                    </xsd:restriction>
+                </xsd:simpleType>
+            </xsd:element>
+
+            <xsd:element name="ydpi" minOccurs="0">
+                <xsd:annotation>
+                    <xsd:documentation xml:lang="en">
+                        Specifies the actual density in Y of the device screen.
+                    </xsd:documentation>
+                </xsd:annotation>
+                <xsd:simpleType>
+                    <xsd:restriction base="xsd:float">
+                        <xsd:minExclusive value="0" />
+                    </xsd:restriction>
+                </xsd:simpleType>
+            </xsd:element>
+
         </xsd:all>
     </xsd:complexType>
 
diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java
index 45332f2..43b0507 100755
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/TestLayoutConfisXsd.java
@@ -104,6 +104,42 @@
 

     // --- Helpers ------------

 

+    /** An helper that validates a string against an expected regexp. */

+    private void assertRegex(String expectedRegexp, String actualString) {

+        assertNotNull(actualString);

+        assertTrue(

+                String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n",

+                        expectedRegexp, actualString),

+                actualString.matches(expectedRegexp));

+    }

+

+    public void checkFailure(String document, String regexp) throws Exception {

+        Source source = new StreamSource(new StringReader(document));

+

+        // don't capture the validator errors, we want it to fail and catch the exception

+        Validator validator = LayoutConfigsXsd.getValidator(null);

+        try {

+            validator.validate(source);

+        } catch (SAXParseException e) {

+            // We expect a parse expression referring to this grammar rule

+            assertRegex(regexp, e.getMessage());

+            return;

+        }

+        // If we get here, the validator has not failed as we expected it to.

+        fail();

+    }

+

+    public void checkSuccess(String document) throws Exception {

+        Source source = new StreamSource(new StringReader(document));

+

+        CaptureErrorHandler handler = new CaptureErrorHandler();

+        Validator validator = LayoutConfigsXsd.getValidator(null);

+        validator.validate(source);

+        handler.verify();

+    }

+

+    // --- Tests ------------

+

     /** Validate a valid sample using an InputStream */

     public void testValidateLocalRepositoryFile() throws Exception {

 

@@ -117,171 +153,180 @@
         handler.verify();

     }

 

-    /** An helper that validates a string against an expected regexp. */

-    private void assertRegex(String expectedRegexp, String actualString) {

-        assertNotNull(actualString);

-        assertTrue(

-                String.format("Regexp Assertion Failed:\nExpected: %s\nActual: %s\n",

-                        expectedRegexp, actualString),

-                actualString.matches(expectedRegexp));

-    }

-

-    // --- Tests ------------

-

     /** A document should at least have a root to be valid */

     public void testEmptyXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        CaptureErrorHandler handler = new CaptureErrorHandler();

-        Validator validator = LayoutConfigsXsd.getValidator(handler);

-

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect to get this specific exception message

-            assertRegex("Premature end of file.*", e.getMessage());

-            return;

-        }

-        // We shouldn't get here

-        handler.verify();

-        fail();

+                // expected failure

+                "Premature end of file.*");

     }

 

     /** A document with an unknown element. */

     public void testUnknownContentXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

-            "<d:unknown />" +

-            "</d:layout-configs>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:unknown />" +

+                "</d:layout-configs>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse expression referring to this grammar rule

-            assertRegex("cvc-complex-type.2.4.a: Invalid content was found.*", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.2.4.a: Invalid content was found.*");

     }

 

     /** A document with an missing attribute in a device element. */

     public void testIncompleteContentXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

-            "<d:device />" +

-            "</d:layout-configs>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device />" +

+                "</d:layout-configs>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse error referring to this grammar rule

-            assertRegex("cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.4: Attribute 'name' must appear on element 'd:device'.");

     }

 

     /** A document with a root element containing no device element is not valid. */

     public void testEmptyRootXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" />";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" />",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse expression referring to this grammar rule

-            assertRegex("cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.2.4.b: The content of element 'd:layout-configs' is not complete.*");

     }

 

     /** A document with an empty device element is not valid. */

     public void testEmptyDeviceXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

-            "<d:device name=\"foo\"/>" +

-            "</d:layout-configs>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\"/>" +

+                "</d:layout-configs>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse error referring to this grammar rule

-            assertRegex("cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.2.4.b: The content of element 'd:device' is not complete.*");

     }

 

     /** A document with two default elements in a device element is not valid. */

     public void testTwoDefaultsXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

-            "<d:device name=\"foo\">" +

-            "  <d:default />" +

-            "  <d:default />" +

-            "</d:device>" +

-            "</d:layout-configs>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:default />" +

+                "  <d:default />" +

+                "</d:device>" +

+                "</d:layout-configs>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse error referring to this grammar rule

-            assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");

     }

 

     /** The default elements must be defined before the config one. It's invalid if after. */

     public void testDefaultConfigOrderXml() throws Exception {

-        String document = "<?xml version=\"1.0\"?>" +

-            "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

-            "<d:device name=\"foo\">" +

-            "  <d:config name=\"must-be-after-default\" />" +

-            "  <d:default />" +

-            "</d:device>" +

-            "</d:layout-configs>";

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:config name=\"must-be-after-default\" />" +

+                "  <d:default />" +

+                "</d:device>" +

+                "</d:layout-configs>",

 

-        Source source = new StreamSource(new StringReader(document));

-

-        // don't capture the validator errors, we want it to fail and catch the exception

-        Validator validator = LayoutConfigsXsd.getValidator(null);

-        try {

-            validator.validate(source);

-        } catch (SAXParseException e) {

-            // We expect a parse error referring to this grammar rule

-            assertRegex("cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*", e.getMessage());

-            return;

-        }

-        // If we get here, the validator has not failed as we expected it to.

-        fail();

+                // expected failure

+                "cvc-complex-type.2.4.a: Invalid content was found starting with element 'd:default'.*");

     }

+

+    /** Screen dimension cannot be 0. */

+    public void testScreenDimZeroXml() throws Exception {

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:default>" +

+                "    <d:screen-dimension> <d:size>0</d:size> <d:size>1</d:size> </d:screen-dimension>" +

+                "  </d:default>" +

+                "</d:device>" +

+                "</d:layout-configs>",

+

+                // expected failure

+                "cvc-minInclusive-valid: Value '0' is not facet-valid with respect to minInclusive '1'.*");

+    }

+

+    /** Screen dimension cannot be negative. */

+    public void testScreenDimNegativeXml() throws Exception {

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:default>" +

+                "    <d:screen-dimension> <d:size>-5</d:size> <d:size>1</d:size> </d:screen-dimension>" +

+                "  </d:default>" +

+                "</d:device>" +

+                "</d:layout-configs>",

+

+                // expected failure

+                "cvc-minInclusive-valid: Value '-5' is not facet-valid with respect to minInclusive '1'.*");

+    }

+

+    /** X/Y dpi cannot be 0. */

+    public void testXDpiZeroXml() throws Exception {

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:default>" +

+                "    <d:xdpi>0</d:xdpi>" +

+                "  </d:default>" +

+                "</d:device>" +

+                "</d:layout-configs>",

+

+                // expected failure

+                "cvc-minExclusive-valid: Value '0' is not facet-valid with respect to minExclusive '0.0E1'.*");

+    }

+

+

+    /** X/Y dpi cannot be negative. */

+    public void testXDpiNegativeXml() throws Exception {

+        checkFailure(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:default>" +

+                "    <d:xdpi>-3.1415926538</d:xdpi>" +

+                "  </d:default>" +

+                "</d:device>" +

+                "</d:layout-configs>",

+

+                // expected failure

+                "cvc-minExclusive-valid: Value '-3.1415926538' is not facet-valid with respect to minExclusive '0.0E1'.*");

+    }

+

+    /** WHitespace around token is accepted by the schema. */

+    public void testTokenWhitespaceXml() throws Exception {

+        checkSuccess(

+                // document

+                "<?xml version=\"1.0\"?>" +

+                "<d:layout-configs xmlns:d=\"http://schemas.android.com/sdk/android/layout-configs/1\" >" +

+                "<d:device name=\"foo\">" +

+                "  <d:config name='foo'>" +

+                "    <d:screen-ratio>  \n long \r </d:screen-ratio>" +

+                "  </d:config>" +

+                "</d:device>" +

+                "</d:layout-configs>");

+    }

+

 }

+

diff --git a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml
index 12c481d..901dd71 100755
--- a/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml
+++ b/tools/eclipse/plugins/com.android.ide.eclipse.tests/src/com/android/ide/eclipse/adt/internal/sdk/config_sample.xml
@@ -32,6 +32,8 @@
                 <d:size>240</d:size>    <!-- 2 * int>0 -->

                 <d:size>480</d:size>

             </d:screen-dimension>

+            <d:xdpi>180.81234</d:xdpi>

+            <d:ydpi>180.81234</d:ydpi>

         </d:default>

 

         <d:config name="Portrait">

@@ -117,8 +119,14 @@
             <d:nav-method>nonav</d:nav-method>

         </d:config>

 

-    </d:device>

+        <d:config name="xdpi">

+            <d:xdpi>240</d:xdpi>

+        </d:config>

+        <d:config name="ydpi">

+            <d:ydpi>2800</d:ydpi>

+        </d:config>

 

+    </d:device>

 

     <d:device name="SomePhone">       <!-- 1..n -->

         <d:config name="screen-size-normal">

diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
index c691af7..201c2fe 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/Main.java
@@ -239,6 +239,10 @@
                 SdkCommandLine.OBJECT_PROJECT.equals(directObject)) {
             updateProject();
 
+        } else if (SdkCommandLine.VERB_UPDATE.equals(verb) &&
+                SdkCommandLine.OBJECT_TEST_PROJECT.equals(directObject)) {
+            updateTestProject();
+
         } else if (verb == null && directObject == null) {
             showMainWindow();
 
@@ -345,7 +349,12 @@
         if (parentProject.isAbsolute() == false) {
             // if the path is not absolute, we need to resolve it based on the
             // destination path of the project
-            parentProject = new File(projectDir, pathToMainProject);
+            try {
+                parentProject = new File(projectDir, pathToMainProject).getCanonicalFile();
+            } catch (IOException e) {
+                errorAndExit("Unable to resolve Main project's directory: %1$s",
+                        pathToMainProject);
+            }
         }
 
         if (parentProject.isDirectory() == false) {
@@ -491,6 +500,21 @@
     }
 
     /**
+     * Updates an existing test project with a new path to the main project.
+     */
+    private void updateTestProject() {
+        ProjectCreator creator = new ProjectCreator(mOsSdkFolder,
+                mSdkCommandLine.isVerbose() ? OutputLevel.VERBOSE :
+                    mSdkCommandLine.isSilent() ? OutputLevel.SILENT :
+                        OutputLevel.NORMAL,
+                mSdkLog);
+
+        String projectDir = getProjectLocation(mSdkCommandLine.getParamLocationPath());
+
+        creator.updateTestProject(projectDir, mSdkCommandLine.getParamTestProjectMain());
+    }
+
+    /**
      * Adjusts the project location to make it absolute & canonical relative to the
      * working directory, if any.
      *
diff --git a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
index 35bbd0d..27afd48 100644
--- a/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
+++ b/tools/sdkmanager/app/src/com/android/sdkmanager/SdkCommandLine.java
@@ -192,10 +192,10 @@
                 VERB_UPDATE, OBJECT_PROJECT,
                 "p", KEY_PATH,
                 "Location path of the project", null);
-        define(Mode.STRING, true,
+        define(Mode.STRING, false,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "t", KEY_TARGET_ID,
-                "Target id to set for the project", -1);
+                "Target id to set for the project", null);
         define(Mode.STRING, false,
                 VERB_UPDATE, OBJECT_PROJECT,
                 "n", KEY_NAME,
@@ -214,7 +214,7 @@
         define(Mode.STRING, true,
                 VERB_UPDATE, OBJECT_TEST_PROJECT,
                 "m", KEY_MAIN_PROJECT,
-                "Location path of the project to test", null);
+                "Location path of the project to test, relative to the new project", null);
     }
 
     @Override
@@ -290,6 +290,6 @@
 
     /** Helper to retrieve the --main value. */
     public String getParamTestProjectMain() {
-        return ((String) getValue(null, OBJECT_TEST_PROJECT, KEY_MAIN_PROJECT));
+        return ((String) getValue(null, null, KEY_MAIN_PROJECT));
     }
 }
diff --git a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
index c4ab013..6394795 100644
--- a/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
+++ b/tools/sdkmanager/libs/sdklib/src/com/android/sdklib/internal/project/ProjectCreator.java
@@ -21,6 +21,7 @@
 import com.android.sdklib.SdkConstants;
 import com.android.sdklib.internal.project.ProjectProperties.PropertyType;
 import com.android.sdklib.xml.AndroidManifest;
+import com.android.sdklib.xml.AndroidXPathFactory;
 
 import org.w3c.dom.NodeList;
 import org.xml.sax.InputSource;
@@ -31,18 +32,13 @@
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.Map;
 import java.util.regex.Pattern;
 
-import javax.xml.XMLConstants;
-import javax.xml.namespace.NamespaceContext;
 import javax.xml.xpath.XPath;
 import javax.xml.xpath.XPathConstants;
 import javax.xml.xpath.XPathExpressionException;
-import javax.xml.xpath.XPathFactory;
 
 /**
  * Creates the basic files needed to get an Android project up and running.
@@ -385,23 +381,14 @@
      * @param projectName The project name from --name. Can be null.
      */
     public void updateProject(String folderPath, IAndroidTarget target, String projectName) {
-        // project folder must exist and be a directory, since this is an update
-        File projectFolder = new File(folderPath);
-        if (!projectFolder.isDirectory()) {
-            mLog.error(null, "Project folder '%1$s' is not a valid directory, this is not an Android project you can update.",
-                    projectFolder);
+        // since this is an update, check the folder does point to a project
+        File androidManifest = checkProjectFolder(folderPath);
+        if (androidManifest == null) {
             return;
         }
 
-        // Check AndroidManifest.xml is present
-        File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
-        if (!androidManifest.isFile()) {
-            mLog.error(null,
-                    "%1$s not found in '%2$s', this is not an Android project you can update.",
-                    SdkConstants.FN_ANDROID_MANIFEST_XML,
-                    folderPath);
-            return;
-        }
+        // get the parent File.
+        File projectFolder = androidManifest.getParentFile();
 
         // Check there's a default.properties with a target *or* --target was specified
         ProjectProperties props = ProjectProperties.load(folderPath, PropertyType.DEFAULT);
@@ -483,9 +470,16 @@
                 keywords.put(PH_PROJECT_NAME, projectName);
             } else {
                 extractPackageFromManifest(androidManifest, keywords);
-                if (keywords.containsKey(PH_ACTIVITY_NAME)) {
+                if (keywords.containsKey(PH_ACTIVITY_ENTRY_NAME)) {
+                    String activity = keywords.get(PH_ACTIVITY_ENTRY_NAME);
+                    // keep only the last segment if applicable
+                    int pos = activity.lastIndexOf('.');
+                    if (pos != -1) {
+                        activity = activity.substring(pos + 1);
+                    }
+
                     // Use the activity as project name
-                    keywords.put(PH_PROJECT_NAME, keywords.get(PH_ACTIVITY_NAME));
+                    keywords.put(PH_PROJECT_NAME, activity);
                 } else {
                     // We need a project name. Just pick up the basename of the project
                     // directory.
@@ -511,6 +505,84 @@
     }
 
     /**
+     * Updates a test project with a new path to the main (tested) project.
+     * @param folderPath the path of the test project.
+     * @param pathToMainProject the path to the main project, relative to the test project.
+     */
+    public void updateTestProject(final String folderPath, final String pathToMainProject) {
+        // since this is an update, check the folder does point to a project
+        if (checkProjectFolder(folderPath) == null) {
+            return;
+        }
+
+        // check the path to the main project is valid.
+        File mainProject = new File(pathToMainProject);
+        String resolvedPath;
+        if (mainProject.isAbsolute() == false) {
+            mainProject = new File(folderPath, pathToMainProject);
+            try {
+                resolvedPath = mainProject.getCanonicalPath();
+            } catch (IOException e) {
+                mLog.error(e, "Unable to resolve path to main project: %1$s", pathToMainProject);
+                return;
+            }
+        } else {
+            resolvedPath = mainProject.getAbsolutePath();
+        }
+
+        println("Resolved location of main project to: %1$s", resolvedPath);
+
+        // check the main project exists
+        if (checkProjectFolder(resolvedPath) == null) {
+            return;
+        }
+
+        ProjectProperties props = ProjectProperties.create(folderPath, PropertyType.BUILD);
+
+        // set or replace the path to the main project
+        props.setProperty(ProjectProperties.PROPERTY_TESTED_PROJECT, pathToMainProject);
+        try {
+            props.save();
+            println("Updated %1$s", PropertyType.BUILD.getFilename());
+        } catch (IOException e) {
+            mLog.error(e, "Failed to write %1$s file in '%2$s'",
+                    PropertyType.BUILD.getFilename(),
+                    folderPath);
+            return;
+        }
+    }
+
+    /**
+     * Checks whether the give <var>folderPath</var> is a valid project folder, and returns
+     * a {@link File} to the AndroidManifest.xml file.
+     * <p/>This checks that the folder exists and contains an AndroidManifest.xml file in it.
+     * <p/>Any error are output using {@link #mLog}.
+     * @param folderPath the folder to check
+     * @return a {@link File} to the AndroidManifest.xml file, or null otherwise.
+     */
+    private File checkProjectFolder(String folderPath) {
+        // project folder must exist and be a directory, since this is an update
+        File projectFolder = new File(folderPath);
+        if (!projectFolder.isDirectory()) {
+            mLog.error(null, "Project folder '%1$s' is not a valid directory, this is not an Android project you can update.",
+                    projectFolder);
+            return null;
+        }
+
+        // Check AndroidManifest.xml is present
+        File androidManifest = new File(projectFolder, SdkConstants.FN_ANDROID_MANIFEST_XML);
+        if (!androidManifest.isFile()) {
+            mLog.error(null,
+                    "%1$s not found in '%2$s', this is not an Android project you can update.",
+                    SdkConstants.FN_ANDROID_MANIFEST_XML,
+                    folderPath);
+            return null;
+        }
+
+        return androidManifest;
+    }
+
+    /**
      * Returns true if any line of the input file contains the requested regexp.
      */
     private boolean checkFileContainsRegexp(File file, String regexp) {
@@ -538,7 +610,7 @@
      * Extracts a "full" package & activity name from an AndroidManifest.xml.
      * <p/>
      * The keywords dictionary is always filed the package name under the key {@link #PH_PACKAGE}.
-     * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_NAME}.
+     * If an activity name can be found, it is filed under the key {@link #PH_ACTIVITY_ENTRY_NAME}.
      * When no activity is found, this key is not created.
      *
      * @param manifestFile The AndroidManifest.xml file
@@ -548,37 +620,7 @@
     private boolean extractPackageFromManifest(File manifestFile,
             Map<String, String> outKeywords) {
         try {
-            final String nsPrefix = "android";
-            final String nsURI = SdkConstants.NS_RESOURCES;
-
-            XPath xpath = XPathFactory.newInstance().newXPath();
-
-            xpath.setNamespaceContext(new NamespaceContext() {
-                public String getNamespaceURI(String prefix) {
-                    if (nsPrefix.equals(prefix)) {
-                        return nsURI;
-                    }
-                    return XMLConstants.NULL_NS_URI;
-                }
-
-                public String getPrefix(String namespaceURI) {
-                    if (nsURI.equals(namespaceURI)) {
-                        return nsPrefix;
-                    }
-                    return null;
-                }
-
-                @SuppressWarnings("unchecked")
-                public Iterator getPrefixes(String namespaceURI) {
-                    if (nsURI.equals(namespaceURI)) {
-                        ArrayList<String> list = new ArrayList<String>();
-                        list.add(nsPrefix);
-                        return list.iterator();
-                    }
-                    return null;
-                }
-
-            });
+            XPath xpath = AndroidXPathFactory.newXPath();
 
             InputSource source = new InputSource(new FileReader(manifestFile));
             String packageName = xpath.evaluate("/manifest/@package", source);
@@ -592,7 +634,7 @@
             String expression = String.format("/manifest/application/activity" +
                     "[intent-filter/action/@%1$s:name='android.intent.action.MAIN' and " +
                     "intent-filter/category/@%1$s:name='android.intent.category.LAUNCHER']" +
-                    "/@%1$s:name", nsPrefix);
+                    "/@%1$s:name", AndroidXPathFactory.DEFAULT_NS_PREFIX);
 
             NodeList activityNames = (NodeList) xpath.evaluate(expression, source,
                     XPathConstants.NODESET);
@@ -632,9 +674,9 @@
             if (activityName.length() == 0) {
                 mLog.warning("Missing <activity %1$s:name=\"...\"> in '%2$s'.\n" +
                         "No activity will be generated.",
-                        nsPrefix, manifestFile.getName());
+                        AndroidXPathFactory.DEFAULT_NS_PREFIX, manifestFile.getName());
             } else {
-                outKeywords.put(PH_ACTIVITY_NAME, activityName);
+                outKeywords.put(PH_ACTIVITY_ENTRY_NAME, activityName);
             }
 
             outKeywords.put(PH_PACKAGE, packageName);